├── .gitignore ├── Makefile ├── README.md ├── lib ├── addrs-flash.inc ├── addrs-ram.inc ├── crt0.s ├── cursorx_lookup.inc ├── font │ ├── spleen-5x8.bdf │ ├── spleen-5x8.hex │ └── spleen-5x8.inc ├── getchar.s ├── mailstation.h ├── mailstation.inc ├── meta_keys.h ├── putchar.s ├── scancodes.inc ├── tools │ ├── generate_cursorx_lookup.rb │ ├── generate_scancodes.rb │ ├── hexfont2inc.rb │ └── relink_packed.rb └── wifi.s └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | obj/* 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # MailStation example program 3 | # Copyright (c) 2019-2021 joshua stein 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any 6 | # purpose with or without fee is hereby granted, provided that the above 7 | # copyright notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | 18 | # the name of your program 19 | PROG= hello 20 | 21 | # your c source files 22 | SRCS= main.c 23 | 24 | # your asm source files 25 | ASM_SRCS= 26 | 27 | # default to build running from ram 28 | LOC?= ram 29 | 30 | 31 | ASZ80?= sdasz80 -l -ff 32 | SDCC?= sdcc -mz80 --opt-code-size 33 | 34 | SRCDIR?= ${.CURDIR} 35 | 36 | OBJ?= ${SRCDIR}/obj 37 | 38 | .if ${LOC} == "flash" 39 | BASE_ADDR= 0x4000 40 | DEFS+= -DLOC_FLASH 41 | .elif ${LOC} == "ram" 42 | BASE_ADDR= 0x8000 43 | DEFS+= -DLOC_RAM 44 | .else 45 | .BEGIN: 46 | @echo 'LOC must be "flash" or "ram"' 47 | @exit 1 48 | .endif 49 | 50 | all: checkobj $(PROG).bin 51 | 52 | obj: .PHONY 53 | mkdir $(OBJ) 54 | 55 | # it would be nice to just make this ourselves but if it doesn't exist before 56 | # make is invoked, it screws things up 57 | checkobj: .PHONY 58 | @if [ ! -d $(OBJ) ]; then \ 59 | echo "\"${MAKE} obj\" first"; \ 60 | exit 1; \ 61 | fi 62 | 63 | clean: 64 | rm -rf $(OBJ)/* 65 | 66 | # assembly 67 | 68 | ADDRS_INC= ${SRCDIR}/lib/addrs-${LOC}.inc 69 | 70 | crt0.rel: lib/crt0.s 71 | $(ASZ80) -o ${.TARGET} ${ADDRS_INC} $> 72 | 73 | getchar.rel: lib/getchar.s 74 | $(ASZ80) -o ${.TARGET} ${ADDRS_INC} $> 75 | 76 | putchar.rel: lib/putchar.s lib/font/spleen-5x8.inc 77 | $(ASZ80) -o ${.TARGET} ${ADDRS_INC} $(SRCDIR)/lib/putchar.s 78 | 79 | wifi.rel: lib/wifi.s 80 | $(ASZ80) -o ${.TARGET} ${ADDRS_INC} $> 81 | 82 | # generated code 83 | 84 | $(SRCDIR)/lib/font/spleen-5x8.inc: $(SRCDIR)/lib/font/spleen-5x8.hex 85 | ruby $(SRCDIR)/lib/tools/hexfont2inc.rb $> > ${.TARGET} 86 | 87 | # all relocation files for final ihx 88 | REL_FILES= crt0.rel putchar.rel getchar.rel wifi.rel 89 | 90 | .for S in $(SRCS) 91 | REL_FILES+= ${S:R}.rel 92 | ${S:R}.rel: $(S) 93 | $(SDCC) $(DEFS) -c ${.TARGET} $(SRCDIR)/$(S) 94 | .endfor 95 | 96 | .for S in $(ASM_SRCS) 97 | REL_FILES+= ${S:R}.rel 98 | ${S:R}.rel: $(S) 99 | $(ASZ80) $(DEFS) -o ${.TARGET} ${ADDRS_INC} $> 100 | .endfor 101 | 102 | # link 103 | 104 | $(PROG).ihx: $(REL_FILES) 105 | @SDCC="$(SDCC) --no-std-crt0" TARGET="$(.TARGET)" \ 106 | BASE_ADDR="$(BASE_ADDR)" CODE_OFF="$(CODE_OFF)" \ 107 | PROG_MAP="$(PROG).map" \ 108 | ruby $(SRCDIR)/lib/tools/relink_packed.rb $> 109 | 110 | # convert to binary 111 | 112 | $(PROG).bin: $(PROG).ihx 113 | objcopy -Iihex -Obinary $> $@ 114 | @if [ `stat -f '%z' ${.TARGET}` -gt 16384 ]; then \ 115 | ls -l ${.TARGET}; \ 116 | echo "${.TARGET} overflows a ${LOC} page, must be <= 16384; increase DATA_SIZE"; \ 117 | exit 1; \ 118 | fi 119 | 120 | # helpers 121 | 122 | disasm: $(PROG).bin 123 | z80dasm -al -g ${BASE_ADDR} $> > $(PROG).dasm 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MailStation Example Program 2 | 3 | This is an example program to get you started writing code for the 4 | [Cidco MailStation](https://jcs.org/2019/05/03/mailstation) 5 | Z80 computer. 6 | 7 | The code in `lib/` sets up the C run-time (`crt0`) and gives you a `putchar` 8 | routine that draws on the screen with a 5x8 font. 9 | 10 | `main()` prints "Hello, World" and then loops forever echoing any keys typed on 11 | the keyboard out to the screen. 12 | This is where your code should go to do something more useful. 13 | 14 | ## Building 15 | 16 | Install 17 | [SDCC](http://sdcc.sourceforge.net/), 18 | Ruby, 19 | and if on a non-BSD platform, a BSD Make (bmake). 20 | 21 | Once installed, issue `make` (or `bmake`): 22 | 23 | $ make obj 24 | $ make 25 | 26 | This will produce a file `obj/hello.bin` for uploading to the MailStation. 27 | 28 | By default, the linker sets up the program to be running from RAM (loaded via 29 | [WSLoader](https://jcs.org/wifistation/loader)) at `0x4000`. 30 | If loading to Data Flash, set `LOC` to `flash` (and clean first): 31 | 32 | $ make LOC=flash clean all 33 | 34 | ## Running 35 | 36 | Run Loader/WSLoader on the MailStation and then upload `obj/hello.bin` to it 37 | via a parallel LapLink cable or a 38 | [WiFiStation](https://jcs.org/wifistation). 39 | 40 | ## Extending 41 | 42 | If your code extends beyond `main.c`, add your source `.c` files to the `SRCS` 43 | variable in `Makefile`, and any assembly files to `ASM_SRCS`. 44 | 45 | You'll probably also want to change the `PROG` variable to be something 46 | meaningful. 47 | 48 | ## License (ISC) 49 | 50 | Copyright (c) 2019-2021 joshua stein 51 | 52 | Permission to use, copy, modify, and distribute this software for any 53 | purpose with or without fee is hereby granted, provided that the above 54 | copyright notice and this permission notice appear in all copies. 55 | 56 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 57 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 58 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 59 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 60 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 61 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 62 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 63 | -------------------------------------------------------------------------------- /lib/addrs-flash.inc: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8:sw=8 2 | ; 3 | ; Copyright (c) 2019-2021 joshua stein 4 | ; 5 | ; Permission to use, copy, modify, and distribute this software for any 6 | ; purpose with or without fee is hereby granted, provided that the above 7 | ; copyright notice and this permission notice appear in all copies. 8 | ; 9 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | ; 17 | 18 | ; When running from Data Flash Loader, we are loaded at 0x4000 19 | ; and use slot 8 for swapping devices 20 | 21 | .equ RUN_ADDR, #0x4000 22 | .equ RUN_DEVICE, #0x6 23 | .equ RUN_PAGE, #0x5 24 | .equ SLOT_ADDR, #0x8000 25 | .equ SLOT_DEVICE, #0x8 26 | .equ SLOT_PAGE, #0x7 27 | -------------------------------------------------------------------------------- /lib/addrs-ram.inc: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8:sw=8 2 | ; 3 | ; Copyright (c) 2019-2021 joshua stein 4 | ; 5 | ; Permission to use, copy, modify, and distribute this software for any 6 | ; purpose with or without fee is hereby granted, provided that the above 7 | ; copyright notice and this permission notice appear in all copies. 8 | ; 9 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | ; 17 | 18 | ; When running from Loader/WSLoader, we are loaded at 0x8000 19 | ; and use slot 4 for swapping devices 20 | 21 | .equ RUN_ADDR, #0x8000 22 | .equ RUN_DEVICE, #0x8 23 | .equ RUN_PAGE, #0x7 24 | .equ SLOT_ADDR, #0x4000 25 | .equ SLOT_DEVICE, #0x6 26 | .equ SLOT_PAGE, #0x5 27 | -------------------------------------------------------------------------------- /lib/crt0.s: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8 2 | ; 3 | ; MailStation example program 4 | ; Copyright (c) 2019-2021 joshua stein 5 | ; 6 | ; Permission to use, copy, modify, and distribute this software for any 7 | ; purpose with or without fee is hereby granted, provided that the above 8 | ; copyright notice and this permission notice appear in all copies. 9 | ; 10 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | ; 18 | 19 | .module crt0 20 | 21 | .include "mailstation.inc" 22 | .globl _main 23 | .globl l__INITIALIZER 24 | .globl s__INITIALIZER 25 | .globl s__INITIALIZED 26 | 27 | .area _HEADER (ABS) 28 | 29 | .org RUN_ADDR 30 | start: 31 | jp boot 32 | 33 | .dw (icons) 34 | .dw (caption) 35 | .dw (dunno) 36 | 37 | dunno: 38 | .db #0 39 | xpos: 40 | .dw #0 41 | ypos: 42 | .dw #0 43 | caption: 44 | .dw #0x0001 ; ? 45 | .dw (endcap - caption - 6) ; number of chars 46 | .dw #0x0006 ; offset to first char 47 | .ascii "Example" ; the caption string 48 | endcap: 49 | 50 | icons: 51 | .dw (icon2 - icon1) ; size of icon1 52 | .dw (icon1 - icons) ; offset to icon1 53 | .dw (iconend - icon2) ; size of icon2 54 | .dw (icon2 - icons) ; offset to icon2 55 | 56 | icon1: 57 | .dw #0x0022 ; icon width (34, 5 bytes per row) 58 | .db #0x22 ; icon height (34) 59 | 60 | .db #0x00, #0x00, #0x00, #0x00, #0x00 ; .................................. 61 | .db #0x00, #0x00, #0x00, #0x00, #0x00 ; .................................. 62 | .db #0x00, #0xc0, #0x0f, #0x00, #0x00 ; ..............######.............. 63 | .db #0x00, #0x30, #0x30, #0x00, #0x00 ; ............##......##............ 64 | .db #0x00, #0x0c, #0xc0, #0x00, #0x00 ; ..........##..........##.......... 65 | .db #0x00, #0x02, #0x00, #0x01, #0x00 ; .........#..............#......... 66 | .db #0x00, #0x01, #0x00, #0x02, #0x00 ; ........#................#........ 67 | .db #0x80, #0x00, #0x00, #0x04, #0x00 ; .......#..................#....... 68 | .db #0x40, #0x00, #0x00, #0x08, #0x00 ; ......#....................#...... 69 | .db #0x20, #0x00, #0x00, #0x10, #0x00 ; .....#......................#..... 70 | .db #0x10, #0x00, #0x00, #0x20, #0x00 ; ....#........................#.... 71 | .db #0x10, #0x00, #0x00, #0x20, #0x00 ; ....#........................#.... 72 | .db #0x08, #0x30, #0x30, #0x40, #0x00 ; ...#........##......##........#... 73 | .db #0x08, #0x78, #0x78, #0x40, #0x00 ; ...#.......####....####.......#... 74 | .db #0x08, #0x78, #0x78, #0x40, #0x00 ; ...#.......####....####.......#... 75 | .db #0x04, #0x30, #0x30, #0x80, #0x00 ; ..#.........##......##.........#.. 76 | .db #0x04, #0x00, #0x00, #0x80, #0x00 ; ..#............................#.. 77 | .db #0x04, #0x00, #0x00, #0x80, #0x00 ; ..#............................#.. 78 | .db #0x04, #0x00, #0x00, #0x80, #0x00 ; ..#............................#.. 79 | .db #0x08, #0x00, #0x00, #0x40, #0x00 ; ...#..........................#... 80 | .db #0x08, #0x00, #0x00, #0x40, #0x00 ; ...#..........................#... 81 | .db #0x08, #0x04, #0x80, #0x40, #0x00 ; ...#......#............#......#... 82 | .db #0x10, #0x04, #0x80, #0x20, #0x00 ; ....#.....#............#.....#.... 83 | .db #0x10, #0x08, #0x40, #0x20, #0x00 ; ....#......#..........#......#.... 84 | .db #0x20, #0x70, #0x38, #0x10, #0x00 ; .....#......###....###......#..... 85 | .db #0x40, #0x80, #0x07, #0x08, #0x00 ; ......#........####........#...... 86 | .db #0x80, #0x00, #0x00, #0x04, #0x00 ; .......#..................#....... 87 | .db #0x00, #0x01, #0x00, #0x02, #0x00 ; ........#................#........ 88 | .db #0x00, #0x02, #0x00, #0x01, #0x00 ; .........#..............#......... 89 | .db #0x00, #0x0c, #0xc0, #0x00, #0x00 ; ..........##..........##.......... 90 | .db #0x00, #0x30, #0x30, #0x00, #0x00 ; ............##......##............ 91 | .db #0x00, #0xc0, #0x0f, #0x00, #0x00 ; ..............######.............. 92 | .db #0x00, #0x00, #0x00, #0x00, #0x00 ; .................................. 93 | .db #0x00, #0x00, #0x00, #0x00, #0x00 ; .................................. 94 | 95 | icon2: 96 | ; not used 97 | .dw #0x0000 ; width 98 | .db #0x00 ; height 99 | iconend: 100 | 101 | boot: 102 | xor a 103 | out (#0x0d), a ; put the cpu in its highest speed 104 | 105 | ; all of our code expects to run in ram so when we're running from 106 | ; dataflash, we have to copy our page of flash into ram, then jump to 107 | ; it 108 | 109 | ; swap in a page of ram 110 | ld a, #DEVICE_RAM 111 | out (#SLOT_DEVICE), a 112 | out (#SLOT_PAGE), a 113 | 114 | ; copy ourselves into ram 115 | ld de, #SLOT_ADDR 116 | ld hl, #RUN_ADDR 117 | ld bc, #0x4000 118 | ldir ; ld (de), (hl), de++, hl++, bc-- 119 | 120 | jp SLOT_ADDR + (hijump - start) 121 | 122 | hijump: 123 | ; PC is now in SLOT_ADDR, put our new RAM page into RUN_DEVICE/PAGE 124 | out (#RUN_DEVICE), a 125 | out (#RUN_PAGE), a 126 | 127 | ; then jump back there 128 | jp RUN_ADDR + (lojump - start) 129 | 130 | lojump: 131 | call gsinit 132 | call find_shadows 133 | call _main ; main c code 134 | jp _exit 135 | 136 | 137 | .area _DATA 138 | 139 | ; shadow locations 140 | p2shadow: 141 | .dw #0xdba2 142 | p3shadow: 143 | .dw #0xdba3 144 | p28shadow: 145 | .dw #0xdba0 146 | delay_func: 147 | jp 0x0a5c 148 | 149 | _debug0:: 150 | .db #0 151 | _debug1:: 152 | .db #0 153 | _debug2:: 154 | .db #0 155 | _debug3:: 156 | .db #0 157 | _debug4:: 158 | .db #0 159 | 160 | 161 | .area _GSINIT 162 | gsinit: 163 | ld bc, #l__INITIALIZER 164 | ld a, b 165 | or a, c 166 | jr z, gsinit_next 167 | ld de, #s__INITIALIZED 168 | ld hl, #s__INITIALIZER 169 | ldir 170 | gsinit_next: 171 | 172 | .area _GSFINAL 173 | ret 174 | 175 | 176 | .area _CODE 177 | 178 | ; set location of port shadow variables depending on firmware version 179 | find_shadows: 180 | ld a, (#0x0037) ; firmware major version 181 | cp #0x1 182 | jr z, ver_1 183 | cp #0x2 184 | jr z, ver_2 185 | cp #0x3 186 | jr z, ver_3 187 | unrecognized_firmware: ; we can't blink because that requires 188 | jp 0x0 ; port and fw function addresses 189 | ver_1: 190 | ld a, (#0x0036) ; firmware minor version 191 | cp #0x73 192 | jr z, ver_1_73 193 | jr unrecognized_firmware 194 | ver_1_73: ; eMessage 1.73CID 195 | ld hl, #p2shadow 196 | ld (hl), #0xdb9f 197 | ld hl, #p3shadow 198 | ld (hl), #0xdba0 ; TODO: verify 199 | ret 200 | ver_2: 201 | ld a, (#0x0036) ; firmware minor version 202 | cp #0x54 203 | jr z, ver_2_54 204 | jr unrecognized_firmware 205 | ver_2_54: ; MailStation 2.54 206 | ld hl, #p2shadow 207 | ld (hl), #0xdba2 208 | ld hl, #p3shadow 209 | ld (hl), #0xdba3 210 | ld hl, #p28shadow 211 | ld (hl), #0xdba0 212 | ret 213 | ver_3: 214 | ld a, (#0x0036) ; firmware minor version 215 | cp #0x0d3 216 | jr z, ver_3_03 217 | jr unrecognized_firmware 218 | ver_3_03: ; MailStation 3.03 219 | ld hl, #p2shadow 220 | ld (hl), #0xdba5 221 | ld hl, #p3shadow 222 | ld (hl), #0xdba6 223 | ret 224 | 225 | ; exit handler, restart 226 | _exit:: 227 | call _reboot 228 | 229 | _powerdown:: 230 | ; TODO: figure out what else needs to be set before shutting down to 231 | ; prevent it going to the "Reset System Data" screen on next startup 232 | ld hl, (#p28shadow) 233 | ld a, (hl) 234 | set 1, a ; 74c74 pin4 235 | set 0, a ; modem reset 236 | ld (hl), a 237 | di 238 | out (#0x28), a 239 | halt 240 | ret 241 | 242 | _reboot:: 243 | jp 0x0000 244 | 245 | ; new_mail(unsigned char on) 246 | ; toggles 'new mail' light 247 | _new_mail:: 248 | di 249 | push ix 250 | ld ix, #0 251 | add ix, sp 252 | push hl 253 | push af 254 | ld a, 4(ix) 255 | cp #0 256 | ld hl, (p2shadow) 257 | jr z, light_off 258 | light_on: 259 | ld a, (hl) 260 | set 4, a 261 | jr write_p2 262 | light_off: 263 | ld a, (hl) 264 | res 4, a 265 | write_p2: 266 | ld (hl), a 267 | out (#0x02), a ; write p2shadow to port2 268 | pop af 269 | pop hl 270 | pop ix 271 | ei 272 | ret 273 | 274 | ; delay(unsigned int millis) 275 | ; call mailstation function that delays (stack) milliseconds 276 | _delay:: 277 | push ix 278 | ld ix, #0 279 | add ix, sp 280 | push af 281 | push bc 282 | push hl 283 | ld l, 4(ix) 284 | ld h, 5(ix) 285 | push hl 286 | call delay_func 287 | pop hl 288 | pop hl 289 | pop bc 290 | pop af 291 | pop ix 292 | ret 293 | 294 | ; blink(unsigned int millis) 295 | ; turn new mail LED on, wait millis, turn it off, wait millis 296 | _blink:: 297 | push ix 298 | ld ix, #0 299 | add ix, sp 300 | push hl 301 | ld l, #1 302 | push hl 303 | call _new_mail ; turn it on 304 | pop hl 305 | ld l, 4(ix) 306 | ld h, 5(ix) 307 | push hl 308 | call _delay ; wait 309 | pop hl 310 | ld l, #0 311 | push hl 312 | call _new_mail ; turn it off 313 | pop hl 314 | ld l, 4(ix) 315 | ld h, 5(ix) 316 | push hl 317 | call _delay ; wait 318 | pop hl 319 | pop af 320 | pop ix 321 | ret 322 | 323 | ; void lcd_sleep(void) 324 | ; turn the LCD off 325 | _lcd_sleep:: 326 | di 327 | push hl 328 | ld hl, (p2shadow) 329 | ld a, (hl) 330 | and #0b01111111 ; LCD_ON - turn port2 bit 7 off 331 | ld (hl), a 332 | out (#0x02), a ; write p2shadow to port2 333 | pop hl 334 | ei 335 | ret 336 | 337 | 338 | ; void lcd_wake(void) 339 | ; turn the LCD on 340 | _lcd_wake:: 341 | di 342 | push hl 343 | ld hl, (p2shadow) 344 | ld a, (hl) 345 | or #0b10000000 ; LCD_ON - turn port2 bit 7 on 346 | ld (hl), a 347 | out (#0x02), a ; write p2shadow to port2 348 | pop hl 349 | ei 350 | ret 351 | 352 | ; unsigned char read_port(unsigned char port) 353 | ; return a byte read from a port 354 | _read_port:: 355 | push ix 356 | ld ix, #0 357 | add ix, sp 358 | push af 359 | push bc 360 | ld b, #0 361 | ld c, 4(ix) 362 | in l, (C) 363 | ld h, #0 364 | pop bc 365 | pop af 366 | pop ix 367 | ret 368 | 369 | 370 | ; 8-bit multiplication 371 | ; de * a = hl 372 | mult8:: 373 | ld b, #8 374 | ld hl, #0 375 | mult8_loop: 376 | add hl, hl 377 | rlca 378 | jr nc, mult8_noadd 379 | add hl, de 380 | mult8_noadd: 381 | djnz mult8_loop 382 | mult8_out: 383 | ret 384 | 385 | ; 16-bit multiplication 386 | ; bc * de = hl 387 | mult16: 388 | ld a, b 389 | ld b, #16 390 | ld hl, #0 391 | mult16_loop: 392 | add hl, hl 393 | sla c 394 | rla 395 | jr nc, mult16_noadd 396 | add hl, de 397 | mult16_noadd: 398 | djnz mult16_loop 399 | ret 400 | 401 | 402 | ; 8-bit division 403 | ; divide e by c, store result in a and remainder in b 404 | div8: 405 | xor a 406 | ld b, #8 407 | div8_loop: 408 | rl e 409 | rla 410 | sub c 411 | jr nc, div8_noadd 412 | add a, c 413 | div8_noadd: 414 | djnz div8_loop 415 | ld b,a 416 | ld a,e 417 | rla 418 | cpl 419 | ret 420 | 421 | ; 16-bit division 422 | ; divide bc by de, store result in bc, remainder in hl 423 | div16: 424 | ld hl, #0 425 | ld a, b 426 | ld b, #8 427 | div16_loop1: 428 | rla 429 | adc hl, hl 430 | sbc hl, de 431 | jr nc, div16_noadd1 432 | add hl, de 433 | div16_noadd1: 434 | djnz div16_loop1 435 | rla 436 | cpl 437 | ld b, a 438 | ld a, c 439 | ld c, b 440 | ld b, #8 441 | div16_loop2: 442 | rla 443 | adc hl, hl 444 | sbc hl, de 445 | jr nc, div16_noadd2 446 | add hl, de 447 | div16_noadd2: 448 | djnz div16_loop2 449 | rla 450 | cpl 451 | ld b, c 452 | ld c, a 453 | ret 454 | -------------------------------------------------------------------------------- /lib/cursorx_lookup.inc: -------------------------------------------------------------------------------- 1 | ; AUTOMATICALLY GENERATED FILE - see tools/generate_cursorx_lookup.rb 2 | .db #0x98 ; 10011000 - col group 19, offset 0 3 | .db #0x9d ; 10011101 - col group 19, offset 5 4 | .db #0x92 ; 10010010 - col group 18, offset 2 5 | .db #0x97 ; 10010111 - col group 18, offset 7 6 | .db #0x8c ; 10001100 - col group 17, offset 4 7 | .db #0x81 ; 10000001 - col group 16, offset 1 8 | .db #0x86 ; 10000110 - col group 16, offset 6 9 | .db #0x7b ; 01111011 - col group 15, offset 3 10 | .db #0x70 ; 01110000 - col group 14, offset 0 11 | .db #0x75 ; 01110101 - col group 14, offset 5 12 | .db #0x6a ; 01101010 - col group 13, offset 2 13 | .db #0x6f ; 01101111 - col group 13, offset 7 14 | .db #0x64 ; 01100100 - col group 12, offset 4 15 | .db #0x59 ; 01011001 - col group 11, offset 1 16 | .db #0x5e ; 01011110 - col group 11, offset 6 17 | .db #0x53 ; 01010011 - col group 10, offset 3 18 | .db #0x48 ; 01001000 - col group 9, offset 0 19 | .db #0x4d ; 01001101 - col group 9, offset 5 20 | .db #0x42 ; 01000010 - col group 8, offset 2 21 | .db #0x47 ; 01000111 - col group 8, offset 7 22 | .db #0x3c ; 00111100 - col group 7, offset 4 23 | .db #0x31 ; 00110001 - col group 6, offset 1 24 | .db #0x36 ; 00110110 - col group 6, offset 6 25 | .db #0x2b ; 00101011 - col group 5, offset 3 26 | .db #0x20 ; 00100000 - col group 4, offset 0 27 | .db #0x25 ; 00100101 - col group 4, offset 5 28 | .db #0x1a ; 00011010 - col group 3, offset 2 29 | .db #0x1f ; 00011111 - col group 3, offset 7 30 | .db #0x14 ; 00010100 - col group 2, offset 4 31 | .db #0x09 ; 00001001 - col group 1, offset 1 32 | .db #0x0e ; 00001110 - col group 1, offset 6 33 | .db #0x03 ; 00000011 - col group 0, offset 3 34 | .db #0x98 ; 10011000 - col group 19, offset 0 35 | .db #0x9d ; 10011101 - col group 19, offset 5 36 | .db #0x92 ; 10010010 - col group 18, offset 2 37 | .db #0x97 ; 10010111 - col group 18, offset 7 38 | .db #0x8c ; 10001100 - col group 17, offset 4 39 | .db #0x81 ; 10000001 - col group 16, offset 1 40 | .db #0x86 ; 10000110 - col group 16, offset 6 41 | .db #0x7b ; 01111011 - col group 15, offset 3 42 | .db #0x70 ; 01110000 - col group 14, offset 0 43 | .db #0x75 ; 01110101 - col group 14, offset 5 44 | .db #0x6a ; 01101010 - col group 13, offset 2 45 | .db #0x6f ; 01101111 - col group 13, offset 7 46 | .db #0x64 ; 01100100 - col group 12, offset 4 47 | .db #0x59 ; 01011001 - col group 11, offset 1 48 | .db #0x5e ; 01011110 - col group 11, offset 6 49 | .db #0x53 ; 01010011 - col group 10, offset 3 50 | .db #0x48 ; 01001000 - col group 9, offset 0 51 | .db #0x4d ; 01001101 - col group 9, offset 5 52 | .db #0x42 ; 01000010 - col group 8, offset 2 53 | .db #0x47 ; 01000111 - col group 8, offset 7 54 | .db #0x3c ; 00111100 - col group 7, offset 4 55 | .db #0x31 ; 00110001 - col group 6, offset 1 56 | .db #0x36 ; 00110110 - col group 6, offset 6 57 | .db #0x2b ; 00101011 - col group 5, offset 3 58 | .db #0x20 ; 00100000 - col group 4, offset 0 59 | .db #0x25 ; 00100101 - col group 4, offset 5 60 | .db #0x1a ; 00011010 - col group 3, offset 2 61 | .db #0x1f ; 00011111 - col group 3, offset 7 62 | .db #0x14 ; 00010100 - col group 2, offset 4 63 | .db #0x09 ; 00001001 - col group 1, offset 1 64 | .db #0x0e ; 00001110 - col group 1, offset 6 65 | .db #0x03 ; 00000011 - col group 0, offset 3 66 | -------------------------------------------------------------------------------- /lib/font/spleen-5x8.bdf: -------------------------------------------------------------------------------- 1 | STARTFONT 2.1 2 | COMMENT /* 3 | COMMENT * Spleen 5x8 1.0.3 4 | COMMENT * Copyright (c) 2018, Frederic Cambus 5 | COMMENT * https://www.cambus.net/ 6 | COMMENT * 7 | COMMENT * Created: 2018-08-08 8 | COMMENT * Last Updated: 2018-12-03 9 | COMMENT * 10 | COMMENT * Spleen is released under the BSD 2-Clause license. 11 | COMMENT * See LICENSE file for details. 12 | COMMENT */ 13 | FONT -misc-spleen-medium-r-normal--8-80-72-72-C-50-iso10646-1 14 | SIZE 8 72 72 15 | FONTBOUNDINGBOX 6 8 0 -1 16 | STARTPROPERTIES 18 17 | FAMILY_NAME "Spleen" 18 | FOUNDRY "misc" 19 | SLANT "R" 20 | SETWIDTH_NAME "Normal" 21 | PIXEL_SIZE 8 22 | POINT_SIZE 80 23 | RESOLUTION_X 72 24 | RESOLUTION_Y 72 25 | SPACING "C" 26 | AVERAGE_WIDTH 50 27 | CHARSET_REGISTRY "ISO10646" 28 | CHARSET_ENCODING "1" 29 | MIN_SPACE 5 30 | FONT_DESCENT 1 31 | FONT_ASCENT 7 32 | COPYRIGHT "Copyright (c) 2018, Frederic Cambus" 33 | DEFAULT_CHAR 32 34 | _GBDFED_INFO "Edited with gbdfed 1.6." 35 | ENDPROPERTIES 36 | CHARS 224 37 | STARTCHAR char0 38 | ENCODING 0 39 | SWIDTH 750 0 40 | DWIDTH 6 0 41 | BBX 6 8 0 -1 42 | BITMAP 43 | F8 44 | D8 45 | A8 46 | E8 47 | D8 48 | F8 49 | D8 50 | F8 51 | ENDCHAR 52 | STARTCHAR char1 53 | ENCODING 1 54 | SWIDTH 750 0 55 | DWIDTH 6 0 56 | BBX 6 8 0 -1 57 | BITMAP 58 | 70 59 | 88 60 | D8 61 | 88 62 | F8 63 | 88 64 | 70 65 | 00 66 | ENDCHAR 67 | STARTCHAR char2 68 | ENCODING 2 69 | SWIDTH 750 0 70 | DWIDTH 6 0 71 | BBX 6 8 0 -1 72 | BITMAP 73 | 70 74 | F8 75 | A8 76 | F8 77 | 88 78 | F8 79 | 70 80 | 00 81 | ENDCHAR 82 | STARTCHAR char3 83 | ENCODING 3 84 | SWIDTH 750 0 85 | DWIDTH 6 0 86 | BBX 6 8 0 -1 87 | BITMAP 88 | 00 89 | 50 90 | F8 91 | F8 92 | 70 93 | 20 94 | 00 95 | 00 96 | ENDCHAR 97 | STARTCHAR char4 98 | ENCODING 4 99 | SWIDTH 750 0 100 | DWIDTH 6 0 101 | BBX 6 8 0 -1 102 | BITMAP 103 | 00 104 | 20 105 | 70 106 | F8 107 | 70 108 | 20 109 | 00 110 | 00 111 | ENDCHAR 112 | STARTCHAR char5 113 | ENCODING 5 114 | SWIDTH 750 0 115 | DWIDTH 6 0 116 | BBX 6 8 0 -1 117 | BITMAP 118 | 00 119 | 20 120 | 70 121 | D8 122 | D8 123 | 20 124 | 70 125 | 00 126 | ENDCHAR 127 | STARTCHAR char6 128 | ENCODING 6 129 | SWIDTH 750 0 130 | DWIDTH 6 0 131 | BBX 6 8 0 -1 132 | BITMAP 133 | 00 134 | 20 135 | 70 136 | F8 137 | F8 138 | 20 139 | 70 140 | 00 141 | ENDCHAR 142 | STARTCHAR char7 143 | ENCODING 7 144 | SWIDTH 750 0 145 | DWIDTH 6 0 146 | BBX 6 8 0 -1 147 | BITMAP 148 | 00 149 | 00 150 | 20 151 | 70 152 | 70 153 | 20 154 | 00 155 | 00 156 | ENDCHAR 157 | STARTCHAR char8 158 | ENCODING 8 159 | SWIDTH 750 0 160 | DWIDTH 6 0 161 | BBX 6 8 0 -1 162 | BITMAP 163 | 70 164 | 70 165 | 50 166 | 00 167 | 50 168 | 70 169 | 70 170 | 70 171 | ENDCHAR 172 | STARTCHAR char9 173 | ENCODING 9 174 | SWIDTH 750 0 175 | DWIDTH 6 0 176 | BBX 6 8 0 -1 177 | BITMAP 178 | 00 179 | 00 180 | 20 181 | 50 182 | 50 183 | 20 184 | 00 185 | 00 186 | ENDCHAR 187 | STARTCHAR char10 188 | ENCODING 10 189 | SWIDTH 750 0 190 | DWIDTH 6 0 191 | BBX 6 8 0 -1 192 | BITMAP 193 | 70 194 | 70 195 | 50 196 | 20 197 | 20 198 | 50 199 | 70 200 | 70 201 | ENDCHAR 202 | STARTCHAR char11 203 | ENCODING 11 204 | SWIDTH 750 0 205 | DWIDTH 6 0 206 | BBX 6 8 0 -1 207 | BITMAP 208 | 00 209 | 30 210 | 70 211 | 90 212 | 90 213 | 60 214 | 00 215 | 00 216 | ENDCHAR 217 | STARTCHAR char12 218 | ENCODING 12 219 | SWIDTH 750 0 220 | DWIDTH 6 0 221 | BBX 6 8 0 -1 222 | BITMAP 223 | 00 224 | 20 225 | 50 226 | 50 227 | 20 228 | 70 229 | 20 230 | 00 231 | ENDCHAR 232 | STARTCHAR char13 233 | ENCODING 13 234 | SWIDTH 750 0 235 | DWIDTH 6 0 236 | BBX 6 8 0 -1 237 | BITMAP 238 | 00 239 | 38 240 | 38 241 | 20 242 | E0 243 | C0 244 | 00 245 | 00 246 | ENDCHAR 247 | STARTCHAR char14 248 | ENCODING 14 249 | SWIDTH 750 0 250 | DWIDTH 6 0 251 | BBX 6 8 0 -1 252 | BITMAP 253 | 00 254 | 38 255 | 38 256 | 28 257 | 28 258 | 50 259 | 00 260 | 00 261 | ENDCHAR 262 | STARTCHAR char15 263 | ENCODING 15 264 | SWIDTH 750 0 265 | DWIDTH 6 0 266 | BBX 6 8 0 -1 267 | BITMAP 268 | 00 269 | A8 270 | 70 271 | D8 272 | 70 273 | A8 274 | 00 275 | 00 276 | ENDCHAR 277 | STARTCHAR char16 278 | ENCODING 16 279 | SWIDTH 750 0 280 | DWIDTH 6 0 281 | BBX 6 8 0 -1 282 | BITMAP 283 | 00 284 | 40 285 | 60 286 | 70 287 | 70 288 | 60 289 | 40 290 | 00 291 | ENDCHAR 292 | STARTCHAR char17 293 | ENCODING 17 294 | SWIDTH 750 0 295 | DWIDTH 6 0 296 | BBX 6 8 0 -1 297 | BITMAP 298 | 00 299 | 10 300 | 30 301 | 70 302 | 70 303 | 30 304 | 10 305 | 00 306 | ENDCHAR 307 | STARTCHAR char18 308 | ENCODING 18 309 | SWIDTH 750 0 310 | DWIDTH 6 0 311 | BBX 6 8 0 -1 312 | BITMAP 313 | 00 314 | 20 315 | 70 316 | 20 317 | 70 318 | 20 319 | 00 320 | 00 321 | ENDCHAR 322 | STARTCHAR char19 323 | ENCODING 19 324 | SWIDTH 750 0 325 | DWIDTH 6 0 326 | BBX 6 8 0 -1 327 | BITMAP 328 | 00 329 | 50 330 | 50 331 | 50 332 | 50 333 | 00 334 | 50 335 | 00 336 | ENDCHAR 337 | STARTCHAR char20 338 | ENCODING 20 339 | SWIDTH 750 0 340 | DWIDTH 6 0 341 | BBX 6 8 0 -1 342 | BITMAP 343 | 00 344 | 70 345 | D0 346 | D0 347 | 50 348 | 50 349 | 00 350 | 00 351 | ENDCHAR 352 | STARTCHAR char21 353 | ENCODING 21 354 | SWIDTH 750 0 355 | DWIDTH 6 0 356 | BBX 6 8 0 -1 357 | BITMAP 358 | 60 359 | 90 360 | 60 361 | F0 362 | 70 363 | 90 364 | 60 365 | 00 366 | ENDCHAR 367 | STARTCHAR char22 368 | ENCODING 22 369 | SWIDTH 750 0 370 | DWIDTH 6 0 371 | BBX 6 8 0 -1 372 | BITMAP 373 | 00 374 | 00 375 | 00 376 | 00 377 | 00 378 | F8 379 | F8 380 | 00 381 | ENDCHAR 382 | STARTCHAR char23 383 | ENCODING 23 384 | SWIDTH 750 0 385 | DWIDTH 6 0 386 | BBX 6 8 0 -1 387 | BITMAP 388 | 20 389 | 70 390 | 20 391 | 20 392 | 70 393 | 20 394 | 70 395 | 00 396 | ENDCHAR 397 | STARTCHAR char24 398 | ENCODING 24 399 | SWIDTH 750 0 400 | DWIDTH 6 0 401 | BBX 6 8 0 -1 402 | BITMAP 403 | 20 404 | 70 405 | 20 406 | 20 407 | 20 408 | 20 409 | 00 410 | 00 411 | ENDCHAR 412 | STARTCHAR char25 413 | ENCODING 25 414 | SWIDTH 750 0 415 | DWIDTH 6 0 416 | BBX 6 8 0 -1 417 | BITMAP 418 | 20 419 | 20 420 | 20 421 | 20 422 | 70 423 | 20 424 | 00 425 | 00 426 | ENDCHAR 427 | STARTCHAR char26 428 | ENCODING 26 429 | SWIDTH 750 0 430 | DWIDTH 6 0 431 | BBX 6 8 0 -1 432 | BITMAP 433 | 00 434 | 00 435 | 20 436 | F0 437 | 20 438 | 00 439 | 00 440 | 00 441 | ENDCHAR 442 | STARTCHAR char27 443 | ENCODING 27 444 | SWIDTH 750 0 445 | DWIDTH 6 0 446 | BBX 6 8 0 -1 447 | BITMAP 448 | 00 449 | 00 450 | 40 451 | F0 452 | 40 453 | 00 454 | 00 455 | 00 456 | ENDCHAR 457 | STARTCHAR char28 458 | ENCODING 28 459 | SWIDTH 750 0 460 | DWIDTH 6 0 461 | BBX 6 8 0 -1 462 | BITMAP 463 | 00 464 | 00 465 | 80 466 | 80 467 | F8 468 | 00 469 | 00 470 | 00 471 | ENDCHAR 472 | STARTCHAR char29 473 | ENCODING 29 474 | SWIDTH 750 0 475 | DWIDTH 6 0 476 | BBX 6 8 0 -1 477 | BITMAP 478 | 00 479 | 00 480 | 50 481 | F8 482 | 50 483 | 00 484 | 00 485 | 00 486 | ENDCHAR 487 | STARTCHAR char30 488 | ENCODING 30 489 | SWIDTH 750 0 490 | DWIDTH 6 0 491 | BBX 6 8 0 -1 492 | BITMAP 493 | 00 494 | 00 495 | 20 496 | 70 497 | F8 498 | 00 499 | 00 500 | 00 501 | ENDCHAR 502 | STARTCHAR char31 503 | ENCODING 31 504 | SWIDTH 750 0 505 | DWIDTH 6 0 506 | BBX 6 8 0 -1 507 | BITMAP 508 | 00 509 | 00 510 | F8 511 | 70 512 | 20 513 | 00 514 | 00 515 | 00 516 | ENDCHAR 517 | STARTCHAR SPACE 518 | ENCODING 32 519 | SWIDTH 750 0 520 | DWIDTH 6 0 521 | BBX 6 8 0 -1 522 | BITMAP 523 | 00 524 | 00 525 | 00 526 | 00 527 | 00 528 | 00 529 | 00 530 | 00 531 | ENDCHAR 532 | STARTCHAR EXCLAMATION MARK 533 | ENCODING 33 534 | SWIDTH 750 0 535 | DWIDTH 6 0 536 | BBX 6 8 0 -1 537 | BITMAP 538 | 20 539 | 20 540 | 20 541 | 20 542 | 20 543 | 00 544 | 20 545 | 00 546 | ENDCHAR 547 | STARTCHAR QUOTATION MARK 548 | ENCODING 34 549 | SWIDTH 750 0 550 | DWIDTH 6 0 551 | BBX 6 8 0 -1 552 | BITMAP 553 | 50 554 | 50 555 | 50 556 | 00 557 | 00 558 | 00 559 | 00 560 | 00 561 | ENDCHAR 562 | STARTCHAR NUMBER SIGN 563 | ENCODING 35 564 | SWIDTH 750 0 565 | DWIDTH 6 0 566 | BBX 6 8 0 -1 567 | BITMAP 568 | 00 569 | 50 570 | F8 571 | 50 572 | 50 573 | F8 574 | 50 575 | 00 576 | ENDCHAR 577 | STARTCHAR DOLLAR SIGN 578 | ENCODING 36 579 | SWIDTH 750 0 580 | DWIDTH 6 0 581 | BBX 6 8 0 -1 582 | BITMAP 583 | 20 584 | 70 585 | A0 586 | 60 587 | 30 588 | 30 589 | E0 590 | 20 591 | ENDCHAR 592 | STARTCHAR PERCENT SIGN 593 | ENCODING 37 594 | SWIDTH 750 0 595 | DWIDTH 6 0 596 | BBX 6 8 0 -1 597 | BITMAP 598 | 10 599 | 90 600 | A0 601 | 20 602 | 40 603 | 50 604 | 90 605 | 80 606 | ENDCHAR 607 | STARTCHAR AMPERSAND 608 | ENCODING 38 609 | SWIDTH 750 0 610 | DWIDTH 6 0 611 | BBX 6 8 0 -1 612 | BITMAP 613 | 20 614 | 50 615 | 50 616 | 60 617 | A0 618 | 90 619 | 68 620 | 00 621 | ENDCHAR 622 | STARTCHAR APOSTROPHE 623 | ENCODING 39 624 | SWIDTH 750 0 625 | DWIDTH 6 0 626 | BBX 6 8 0 -1 627 | BITMAP 628 | 20 629 | 20 630 | 20 631 | 00 632 | 00 633 | 00 634 | 00 635 | 00 636 | ENDCHAR 637 | STARTCHAR LEFT PARENTHESIS 638 | ENCODING 40 639 | SWIDTH 750 0 640 | DWIDTH 6 0 641 | BBX 6 8 0 -1 642 | BITMAP 643 | 10 644 | 20 645 | 40 646 | 40 647 | 40 648 | 40 649 | 20 650 | 10 651 | ENDCHAR 652 | STARTCHAR RIGHT PARENTHESIS 653 | ENCODING 41 654 | SWIDTH 750 0 655 | DWIDTH 6 0 656 | BBX 6 8 0 -1 657 | BITMAP 658 | 40 659 | 20 660 | 10 661 | 10 662 | 10 663 | 10 664 | 20 665 | 40 666 | ENDCHAR 667 | STARTCHAR ASTERISK 668 | ENCODING 42 669 | SWIDTH 750 0 670 | DWIDTH 6 0 671 | BBX 6 8 0 -1 672 | BITMAP 673 | 00 674 | 00 675 | 90 676 | 60 677 | F0 678 | 60 679 | 90 680 | 00 681 | ENDCHAR 682 | STARTCHAR PLUS SIGN 683 | ENCODING 43 684 | SWIDTH 750 0 685 | DWIDTH 6 0 686 | BBX 6 8 0 -1 687 | BITMAP 688 | 00 689 | 00 690 | 20 691 | 20 692 | F8 693 | 20 694 | 20 695 | 00 696 | ENDCHAR 697 | STARTCHAR COMMA 698 | ENCODING 44 699 | SWIDTH 750 0 700 | DWIDTH 6 0 701 | BBX 6 8 0 -1 702 | BITMAP 703 | 00 704 | 00 705 | 00 706 | 00 707 | 00 708 | 20 709 | 20 710 | 40 711 | ENDCHAR 712 | STARTCHAR HYPHEN-MINUS 713 | ENCODING 45 714 | SWIDTH 750 0 715 | DWIDTH 6 0 716 | BBX 6 8 0 -1 717 | BITMAP 718 | 00 719 | 00 720 | 00 721 | 00 722 | F0 723 | 00 724 | 00 725 | 00 726 | ENDCHAR 727 | STARTCHAR FULL STOP 728 | ENCODING 46 729 | SWIDTH 750 0 730 | DWIDTH 6 0 731 | BBX 6 8 0 -1 732 | BITMAP 733 | 00 734 | 00 735 | 00 736 | 00 737 | 00 738 | 00 739 | 20 740 | 00 741 | ENDCHAR 742 | STARTCHAR SOLIDUS 743 | ENCODING 47 744 | SWIDTH 750 0 745 | DWIDTH 6 0 746 | BBX 6 8 0 -1 747 | BITMAP 748 | 10 749 | 10 750 | 20 751 | 20 752 | 40 753 | 40 754 | 80 755 | 80 756 | ENDCHAR 757 | STARTCHAR DIGIT ZERO 758 | ENCODING 48 759 | SWIDTH 750 0 760 | DWIDTH 6 0 761 | BBX 6 8 0 -1 762 | BITMAP 763 | 00 764 | 60 765 | 90 766 | B0 767 | D0 768 | 90 769 | 60 770 | 00 771 | ENDCHAR 772 | STARTCHAR DIGIT ONE 773 | ENCODING 49 774 | SWIDTH 750 0 775 | DWIDTH 6 0 776 | BBX 6 8 0 -1 777 | BITMAP 778 | 00 779 | 20 780 | 60 781 | 20 782 | 20 783 | 20 784 | 70 785 | 00 786 | ENDCHAR 787 | STARTCHAR DIGIT TWO 788 | ENCODING 50 789 | SWIDTH 750 0 790 | DWIDTH 6 0 791 | BBX 6 8 0 -1 792 | BITMAP 793 | 00 794 | 60 795 | 90 796 | 10 797 | 60 798 | 80 799 | F0 800 | 00 801 | ENDCHAR 802 | STARTCHAR DIGIT THREE 803 | ENCODING 51 804 | SWIDTH 750 0 805 | DWIDTH 6 0 806 | BBX 6 8 0 -1 807 | BITMAP 808 | 00 809 | 60 810 | 90 811 | 20 812 | 10 813 | 90 814 | 60 815 | 00 816 | ENDCHAR 817 | STARTCHAR DIGIT FOUR 818 | ENCODING 52 819 | SWIDTH 750 0 820 | DWIDTH 6 0 821 | BBX 6 8 0 -1 822 | BITMAP 823 | 00 824 | 80 825 | A0 826 | A0 827 | F0 828 | 20 829 | 20 830 | 00 831 | ENDCHAR 832 | STARTCHAR DIGIT FIVE 833 | ENCODING 53 834 | SWIDTH 750 0 835 | DWIDTH 6 0 836 | BBX 6 8 0 -1 837 | BITMAP 838 | 00 839 | F0 840 | 80 841 | F0 842 | 10 843 | 10 844 | E0 845 | 00 846 | ENDCHAR 847 | STARTCHAR DIGIT SIX 848 | ENCODING 54 849 | SWIDTH 750 0 850 | DWIDTH 6 0 851 | BBX 6 8 0 -1 852 | BITMAP 853 | 00 854 | 60 855 | 80 856 | E0 857 | 90 858 | 90 859 | 60 860 | 00 861 | ENDCHAR 862 | STARTCHAR DIGIT SEVEN 863 | ENCODING 55 864 | SWIDTH 750 0 865 | DWIDTH 6 0 866 | BBX 6 8 0 -1 867 | BITMAP 868 | 00 869 | F0 870 | 90 871 | 20 872 | 20 873 | 40 874 | 40 875 | 00 876 | ENDCHAR 877 | STARTCHAR DIGIT EIGHT 878 | ENCODING 56 879 | SWIDTH 750 0 880 | DWIDTH 6 0 881 | BBX 6 8 0 -1 882 | BITMAP 883 | 00 884 | 60 885 | 90 886 | 60 887 | 90 888 | 90 889 | 60 890 | 00 891 | ENDCHAR 892 | STARTCHAR DIGIT NINE 893 | ENCODING 57 894 | SWIDTH 750 0 895 | DWIDTH 6 0 896 | BBX 6 8 0 -1 897 | BITMAP 898 | 00 899 | 60 900 | 90 901 | 90 902 | 70 903 | 10 904 | 60 905 | 00 906 | ENDCHAR 907 | STARTCHAR COLON 908 | ENCODING 58 909 | SWIDTH 750 0 910 | DWIDTH 6 0 911 | BBX 6 8 0 -1 912 | BITMAP 913 | 00 914 | 00 915 | 00 916 | 20 917 | 00 918 | 00 919 | 20 920 | 00 921 | ENDCHAR 922 | STARTCHAR SEMICOLON 923 | ENCODING 59 924 | SWIDTH 750 0 925 | DWIDTH 6 0 926 | BBX 6 8 0 -1 927 | BITMAP 928 | 00 929 | 00 930 | 00 931 | 20 932 | 00 933 | 20 934 | 20 935 | 40 936 | ENDCHAR 937 | STARTCHAR LESS-THAN SIGN 938 | ENCODING 60 939 | SWIDTH 750 0 940 | DWIDTH 6 0 941 | BBX 6 8 0 -1 942 | BITMAP 943 | 00 944 | 10 945 | 20 946 | 40 947 | 40 948 | 20 949 | 10 950 | 00 951 | ENDCHAR 952 | STARTCHAR EQUALS SIGN 953 | ENCODING 61 954 | SWIDTH 750 0 955 | DWIDTH 6 0 956 | BBX 6 8 0 -1 957 | BITMAP 958 | 00 959 | 00 960 | 00 961 | F0 962 | 00 963 | F0 964 | 00 965 | 00 966 | ENDCHAR 967 | STARTCHAR GREATER-THAN SIGN 968 | ENCODING 62 969 | SWIDTH 750 0 970 | DWIDTH 6 0 971 | BBX 6 8 0 -1 972 | BITMAP 973 | 00 974 | 40 975 | 20 976 | 10 977 | 10 978 | 20 979 | 40 980 | 00 981 | ENDCHAR 982 | STARTCHAR QUESTION MARK 983 | ENCODING 63 984 | SWIDTH 750 0 985 | DWIDTH 6 0 986 | BBX 6 8 0 -1 987 | BITMAP 988 | 60 989 | 90 990 | 10 991 | 20 992 | 40 993 | 00 994 | 40 995 | 00 996 | ENDCHAR 997 | STARTCHAR COMMERCIAL AT 998 | ENCODING 64 999 | SWIDTH 750 0 1000 | DWIDTH 6 0 1001 | BBX 6 8 0 -1 1002 | BITMAP 1003 | 00 1004 | 60 1005 | 90 1006 | B0 1007 | B0 1008 | 80 1009 | 70 1010 | 00 1011 | ENDCHAR 1012 | STARTCHAR LATIN CAPITAL LETTER A 1013 | ENCODING 65 1014 | SWIDTH 750 0 1015 | DWIDTH 6 0 1016 | BBX 6 8 0 -1 1017 | BITMAP 1018 | 00 1019 | 60 1020 | 90 1021 | 90 1022 | F0 1023 | 90 1024 | 90 1025 | 00 1026 | ENDCHAR 1027 | STARTCHAR LATIN CAPITAL LETTER B 1028 | ENCODING 66 1029 | SWIDTH 750 0 1030 | DWIDTH 6 0 1031 | BBX 6 8 0 -1 1032 | BITMAP 1033 | 00 1034 | E0 1035 | 90 1036 | E0 1037 | 90 1038 | 90 1039 | E0 1040 | 00 1041 | ENDCHAR 1042 | STARTCHAR LATIN CAPITAL LETTER C 1043 | ENCODING 67 1044 | SWIDTH 750 0 1045 | DWIDTH 6 0 1046 | BBX 6 8 0 -1 1047 | BITMAP 1048 | 00 1049 | 70 1050 | 80 1051 | 80 1052 | 80 1053 | 80 1054 | 70 1055 | 00 1056 | ENDCHAR 1057 | STARTCHAR LATIN CAPITAL LETTER D 1058 | ENCODING 68 1059 | SWIDTH 750 0 1060 | DWIDTH 6 0 1061 | BBX 6 8 0 -1 1062 | BITMAP 1063 | 00 1064 | E0 1065 | 90 1066 | 90 1067 | 90 1068 | 90 1069 | E0 1070 | 00 1071 | ENDCHAR 1072 | STARTCHAR LATIN CAPITAL LETTER E 1073 | ENCODING 69 1074 | SWIDTH 750 0 1075 | DWIDTH 6 0 1076 | BBX 6 8 0 -1 1077 | BITMAP 1078 | 00 1079 | 70 1080 | 80 1081 | E0 1082 | 80 1083 | 80 1084 | 70 1085 | 00 1086 | ENDCHAR 1087 | STARTCHAR LATIN CAPITAL LETTER F 1088 | ENCODING 70 1089 | SWIDTH 750 0 1090 | DWIDTH 6 0 1091 | BBX 6 8 0 -1 1092 | BITMAP 1093 | 00 1094 | 70 1095 | 80 1096 | 80 1097 | E0 1098 | 80 1099 | 80 1100 | 00 1101 | ENDCHAR 1102 | STARTCHAR LATIN CAPITAL LETTER G 1103 | ENCODING 71 1104 | SWIDTH 750 0 1105 | DWIDTH 6 0 1106 | BBX 6 8 0 -1 1107 | BITMAP 1108 | 00 1109 | 70 1110 | 80 1111 | B0 1112 | 90 1113 | 90 1114 | 70 1115 | 00 1116 | ENDCHAR 1117 | STARTCHAR LATIN CAPITAL LETTER H 1118 | ENCODING 72 1119 | SWIDTH 750 0 1120 | DWIDTH 6 0 1121 | BBX 6 8 0 -1 1122 | BITMAP 1123 | 00 1124 | 90 1125 | 90 1126 | F0 1127 | 90 1128 | 90 1129 | 90 1130 | 00 1131 | ENDCHAR 1132 | STARTCHAR LATIN CAPITAL LETTER I 1133 | ENCODING 73 1134 | SWIDTH 750 0 1135 | DWIDTH 6 0 1136 | BBX 6 8 0 -1 1137 | BITMAP 1138 | 00 1139 | 70 1140 | 20 1141 | 20 1142 | 20 1143 | 20 1144 | 70 1145 | 00 1146 | ENDCHAR 1147 | STARTCHAR LATIN CAPITAL LETTER J 1148 | ENCODING 74 1149 | SWIDTH 750 0 1150 | DWIDTH 6 0 1151 | BBX 6 8 0 -1 1152 | BITMAP 1153 | 00 1154 | 70 1155 | 20 1156 | 20 1157 | 20 1158 | 20 1159 | C0 1160 | 00 1161 | ENDCHAR 1162 | STARTCHAR LATIN CAPITAL LETTER K 1163 | ENCODING 75 1164 | SWIDTH 750 0 1165 | DWIDTH 6 0 1166 | BBX 6 8 0 -1 1167 | BITMAP 1168 | 00 1169 | 90 1170 | 90 1171 | E0 1172 | 90 1173 | 90 1174 | 90 1175 | 00 1176 | ENDCHAR 1177 | STARTCHAR LATIN CAPITAL LETTER L 1178 | ENCODING 76 1179 | SWIDTH 750 0 1180 | DWIDTH 6 0 1181 | BBX 6 8 0 -1 1182 | BITMAP 1183 | 00 1184 | 80 1185 | 80 1186 | 80 1187 | 80 1188 | 80 1189 | 70 1190 | 00 1191 | ENDCHAR 1192 | STARTCHAR LATIN CAPITAL LETTER M 1193 | ENCODING 77 1194 | SWIDTH 750 0 1195 | DWIDTH 6 0 1196 | BBX 6 8 0 -1 1197 | BITMAP 1198 | 00 1199 | 90 1200 | F0 1201 | F0 1202 | 90 1203 | 90 1204 | 90 1205 | 00 1206 | ENDCHAR 1207 | STARTCHAR LATIN CAPITAL LETTER N 1208 | ENCODING 78 1209 | SWIDTH 750 0 1210 | DWIDTH 6 0 1211 | BBX 6 8 0 -1 1212 | BITMAP 1213 | 00 1214 | 90 1215 | D0 1216 | D0 1217 | B0 1218 | B0 1219 | 90 1220 | 00 1221 | ENDCHAR 1222 | STARTCHAR LATIN CAPITAL LETTER O 1223 | ENCODING 79 1224 | SWIDTH 750 0 1225 | DWIDTH 6 0 1226 | BBX 6 8 0 -1 1227 | BITMAP 1228 | 00 1229 | 60 1230 | 90 1231 | 90 1232 | 90 1233 | 90 1234 | 60 1235 | 00 1236 | ENDCHAR 1237 | STARTCHAR LATIN CAPITAL LETTER P 1238 | ENCODING 80 1239 | SWIDTH 750 0 1240 | DWIDTH 6 0 1241 | BBX 6 8 0 -1 1242 | BITMAP 1243 | 00 1244 | E0 1245 | 90 1246 | 90 1247 | E0 1248 | 80 1249 | 80 1250 | 00 1251 | ENDCHAR 1252 | STARTCHAR LATIN CAPITAL LETTER Q 1253 | ENCODING 81 1254 | SWIDTH 750 0 1255 | DWIDTH 6 0 1256 | BBX 6 8 0 -1 1257 | BITMAP 1258 | 00 1259 | 60 1260 | 90 1261 | 90 1262 | 90 1263 | 90 1264 | 60 1265 | 30 1266 | ENDCHAR 1267 | STARTCHAR LATIN CAPITAL LETTER R 1268 | ENCODING 82 1269 | SWIDTH 750 0 1270 | DWIDTH 6 0 1271 | BBX 6 8 0 -1 1272 | BITMAP 1273 | 00 1274 | E0 1275 | 90 1276 | 90 1277 | E0 1278 | 90 1279 | 90 1280 | 00 1281 | ENDCHAR 1282 | STARTCHAR LATIN CAPITAL LETTER S 1283 | ENCODING 83 1284 | SWIDTH 750 0 1285 | DWIDTH 6 0 1286 | BBX 6 8 0 -1 1287 | BITMAP 1288 | 00 1289 | 70 1290 | 80 1291 | 60 1292 | 10 1293 | 10 1294 | E0 1295 | 00 1296 | ENDCHAR 1297 | STARTCHAR LATIN CAPITAL LETTER T 1298 | ENCODING 84 1299 | SWIDTH 750 0 1300 | DWIDTH 6 0 1301 | BBX 6 8 0 -1 1302 | BITMAP 1303 | 00 1304 | F8 1305 | 20 1306 | 20 1307 | 20 1308 | 20 1309 | 20 1310 | 00 1311 | ENDCHAR 1312 | STARTCHAR LATIN CAPITAL LETTER U 1313 | ENCODING 85 1314 | SWIDTH 750 0 1315 | DWIDTH 6 0 1316 | BBX 6 8 0 -1 1317 | BITMAP 1318 | 00 1319 | 90 1320 | 90 1321 | 90 1322 | 90 1323 | 90 1324 | 70 1325 | 00 1326 | ENDCHAR 1327 | STARTCHAR LATIN CAPITAL LETTER V 1328 | ENCODING 86 1329 | SWIDTH 750 0 1330 | DWIDTH 6 0 1331 | BBX 6 8 0 -1 1332 | BITMAP 1333 | 00 1334 | 90 1335 | 90 1336 | 90 1337 | 90 1338 | 60 1339 | 60 1340 | 00 1341 | ENDCHAR 1342 | STARTCHAR LATIN CAPITAL LETTER W 1343 | ENCODING 87 1344 | SWIDTH 750 0 1345 | DWIDTH 6 0 1346 | BBX 6 8 0 -1 1347 | BITMAP 1348 | 00 1349 | 90 1350 | 90 1351 | 90 1352 | F0 1353 | F0 1354 | 90 1355 | 00 1356 | ENDCHAR 1357 | STARTCHAR LATIN CAPITAL LETTER X 1358 | ENCODING 88 1359 | SWIDTH 750 0 1360 | DWIDTH 6 0 1361 | BBX 6 8 0 -1 1362 | BITMAP 1363 | 00 1364 | 90 1365 | 90 1366 | 60 1367 | 60 1368 | 90 1369 | 90 1370 | 00 1371 | ENDCHAR 1372 | STARTCHAR LATIN CAPITAL LETTER Y 1373 | ENCODING 89 1374 | SWIDTH 750 0 1375 | DWIDTH 6 0 1376 | BBX 6 8 0 -1 1377 | BITMAP 1378 | 00 1379 | 90 1380 | 90 1381 | 90 1382 | 70 1383 | 10 1384 | E0 1385 | 00 1386 | ENDCHAR 1387 | STARTCHAR LATIN CAPITAL LETTER Z 1388 | ENCODING 90 1389 | SWIDTH 750 0 1390 | DWIDTH 6 0 1391 | BBX 6 8 0 -1 1392 | BITMAP 1393 | 00 1394 | F0 1395 | 10 1396 | 20 1397 | 40 1398 | 80 1399 | F0 1400 | 00 1401 | ENDCHAR 1402 | STARTCHAR LEFT SQUARE BRACKET 1403 | ENCODING 91 1404 | SWIDTH 750 0 1405 | DWIDTH 6 0 1406 | BBX 6 8 0 -1 1407 | BITMAP 1408 | 70 1409 | 40 1410 | 40 1411 | 40 1412 | 40 1413 | 40 1414 | 40 1415 | 70 1416 | ENDCHAR 1417 | STARTCHAR REVERSE SOLIDUS 1418 | ENCODING 92 1419 | SWIDTH 750 0 1420 | DWIDTH 6 0 1421 | BBX 6 8 0 -1 1422 | BITMAP 1423 | 80 1424 | 80 1425 | 40 1426 | 40 1427 | 20 1428 | 20 1429 | 10 1430 | 10 1431 | ENDCHAR 1432 | STARTCHAR RIGHT SQUARE BRACKET 1433 | ENCODING 93 1434 | SWIDTH 750 0 1435 | DWIDTH 6 0 1436 | BBX 6 8 0 -1 1437 | BITMAP 1438 | 70 1439 | 10 1440 | 10 1441 | 10 1442 | 10 1443 | 10 1444 | 10 1445 | 70 1446 | ENDCHAR 1447 | STARTCHAR CIRCUMFLEX ACCENT 1448 | ENCODING 94 1449 | SWIDTH 750 0 1450 | DWIDTH 6 0 1451 | BBX 6 8 0 -1 1452 | BITMAP 1453 | 00 1454 | 20 1455 | 50 1456 | 88 1457 | 00 1458 | 00 1459 | 00 1460 | 00 1461 | ENDCHAR 1462 | STARTCHAR LOW LINE 1463 | ENCODING 95 1464 | SWIDTH 750 0 1465 | DWIDTH 6 0 1466 | BBX 6 8 0 -1 1467 | BITMAP 1468 | 00 1469 | 00 1470 | 00 1471 | 00 1472 | 00 1473 | 00 1474 | 00 1475 | F0 1476 | ENDCHAR 1477 | STARTCHAR GRAVE ACCENT 1478 | ENCODING 96 1479 | SWIDTH 750 0 1480 | DWIDTH 6 0 1481 | BBX 6 8 0 -1 1482 | BITMAP 1483 | 40 1484 | 20 1485 | 00 1486 | 00 1487 | 00 1488 | 00 1489 | 00 1490 | 00 1491 | ENDCHAR 1492 | STARTCHAR LATIN SMALL LETTER A 1493 | ENCODING 97 1494 | SWIDTH 750 0 1495 | DWIDTH 6 0 1496 | BBX 6 8 0 -1 1497 | BITMAP 1498 | 00 1499 | 00 1500 | 60 1501 | 10 1502 | 70 1503 | 90 1504 | 70 1505 | 00 1506 | ENDCHAR 1507 | STARTCHAR LATIN SMALL LETTER B 1508 | ENCODING 98 1509 | SWIDTH 750 0 1510 | DWIDTH 6 0 1511 | BBX 6 8 0 -1 1512 | BITMAP 1513 | 80 1514 | 80 1515 | E0 1516 | 90 1517 | 90 1518 | 90 1519 | E0 1520 | 00 1521 | ENDCHAR 1522 | STARTCHAR LATIN SMALL LETTER C 1523 | ENCODING 99 1524 | SWIDTH 750 0 1525 | DWIDTH 6 0 1526 | BBX 6 8 0 -1 1527 | BITMAP 1528 | 00 1529 | 00 1530 | 70 1531 | 80 1532 | 80 1533 | 80 1534 | 70 1535 | 00 1536 | ENDCHAR 1537 | STARTCHAR LATIN SMALL LETTER D 1538 | ENCODING 100 1539 | SWIDTH 750 0 1540 | DWIDTH 6 0 1541 | BBX 6 8 0 -1 1542 | BITMAP 1543 | 10 1544 | 10 1545 | 70 1546 | 90 1547 | 90 1548 | 90 1549 | 70 1550 | 00 1551 | ENDCHAR 1552 | STARTCHAR LATIN SMALL LETTER E 1553 | ENCODING 101 1554 | SWIDTH 750 0 1555 | DWIDTH 6 0 1556 | BBX 6 8 0 -1 1557 | BITMAP 1558 | 00 1559 | 00 1560 | 70 1561 | 90 1562 | F0 1563 | 80 1564 | 70 1565 | 00 1566 | ENDCHAR 1567 | STARTCHAR LATIN SMALL LETTER F 1568 | ENCODING 102 1569 | SWIDTH 750 0 1570 | DWIDTH 6 0 1571 | BBX 6 8 0 -1 1572 | BITMAP 1573 | 30 1574 | 40 1575 | 40 1576 | E0 1577 | 40 1578 | 40 1579 | 40 1580 | 00 1581 | ENDCHAR 1582 | STARTCHAR LATIN SMALL LETTER G 1583 | ENCODING 103 1584 | SWIDTH 750 0 1585 | DWIDTH 6 0 1586 | BBX 6 8 0 -1 1587 | BITMAP 1588 | 00 1589 | 00 1590 | 70 1591 | 90 1592 | 90 1593 | 60 1594 | 10 1595 | E0 1596 | ENDCHAR 1597 | STARTCHAR LATIN SMALL LETTER H 1598 | ENCODING 104 1599 | SWIDTH 750 0 1600 | DWIDTH 6 0 1601 | BBX 6 8 0 -1 1602 | BITMAP 1603 | 80 1604 | 80 1605 | E0 1606 | 90 1607 | 90 1608 | 90 1609 | 90 1610 | 00 1611 | ENDCHAR 1612 | STARTCHAR LATIN SMALL LETTER I 1613 | ENCODING 105 1614 | SWIDTH 750 0 1615 | DWIDTH 6 0 1616 | BBX 6 8 0 -1 1617 | BITMAP 1618 | 00 1619 | 20 1620 | 00 1621 | 20 1622 | 20 1623 | 20 1624 | 20 1625 | 00 1626 | ENDCHAR 1627 | STARTCHAR LATIN SMALL LETTER J 1628 | ENCODING 106 1629 | SWIDTH 750 0 1630 | DWIDTH 6 0 1631 | BBX 6 8 0 -1 1632 | BITMAP 1633 | 00 1634 | 20 1635 | 00 1636 | 20 1637 | 20 1638 | 20 1639 | 20 1640 | C0 1641 | ENDCHAR 1642 | STARTCHAR LATIN SMALL LETTER K 1643 | ENCODING 107 1644 | SWIDTH 750 0 1645 | DWIDTH 6 0 1646 | BBX 6 8 0 -1 1647 | BITMAP 1648 | 80 1649 | 80 1650 | 90 1651 | A0 1652 | C0 1653 | A0 1654 | 90 1655 | 00 1656 | ENDCHAR 1657 | STARTCHAR LATIN SMALL LETTER L 1658 | ENCODING 108 1659 | SWIDTH 750 0 1660 | DWIDTH 6 0 1661 | BBX 6 8 0 -1 1662 | BITMAP 1663 | 40 1664 | 40 1665 | 40 1666 | 40 1667 | 40 1668 | 40 1669 | 30 1670 | 00 1671 | ENDCHAR 1672 | STARTCHAR LATIN SMALL LETTER M 1673 | ENCODING 109 1674 | SWIDTH 750 0 1675 | DWIDTH 6 0 1676 | BBX 6 8 0 -1 1677 | BITMAP 1678 | 00 1679 | 00 1680 | 90 1681 | F0 1682 | F0 1683 | 90 1684 | 90 1685 | 00 1686 | ENDCHAR 1687 | STARTCHAR LATIN SMALL LETTER N 1688 | ENCODING 110 1689 | SWIDTH 750 0 1690 | DWIDTH 6 0 1691 | BBX 6 8 0 -1 1692 | BITMAP 1693 | 00 1694 | 00 1695 | E0 1696 | 90 1697 | 90 1698 | 90 1699 | 90 1700 | 00 1701 | ENDCHAR 1702 | STARTCHAR LATIN SMALL LETTER O 1703 | ENCODING 111 1704 | SWIDTH 750 0 1705 | DWIDTH 6 0 1706 | BBX 6 8 0 -1 1707 | BITMAP 1708 | 00 1709 | 00 1710 | 60 1711 | 90 1712 | 90 1713 | 90 1714 | 60 1715 | 00 1716 | ENDCHAR 1717 | STARTCHAR LATIN SMALL LETTER P 1718 | ENCODING 112 1719 | SWIDTH 750 0 1720 | DWIDTH 6 0 1721 | BBX 6 8 0 -1 1722 | BITMAP 1723 | 00 1724 | 00 1725 | E0 1726 | 90 1727 | 90 1728 | E0 1729 | 80 1730 | 80 1731 | ENDCHAR 1732 | STARTCHAR LATIN SMALL LETTER Q 1733 | ENCODING 113 1734 | SWIDTH 750 0 1735 | DWIDTH 6 0 1736 | BBX 6 8 0 -1 1737 | BITMAP 1738 | 00 1739 | 00 1740 | 70 1741 | 90 1742 | 90 1743 | 70 1744 | 10 1745 | 10 1746 | ENDCHAR 1747 | STARTCHAR LATIN SMALL LETTER R 1748 | ENCODING 114 1749 | SWIDTH 750 0 1750 | DWIDTH 6 0 1751 | BBX 6 8 0 -1 1752 | BITMAP 1753 | 00 1754 | 00 1755 | 70 1756 | 90 1757 | 80 1758 | 80 1759 | 80 1760 | 00 1761 | ENDCHAR 1762 | STARTCHAR LATIN SMALL LETTER S 1763 | ENCODING 115 1764 | SWIDTH 750 0 1765 | DWIDTH 6 0 1766 | BBX 6 8 0 -1 1767 | BITMAP 1768 | 00 1769 | 00 1770 | 70 1771 | 80 1772 | 60 1773 | 10 1774 | E0 1775 | 00 1776 | ENDCHAR 1777 | STARTCHAR LATIN SMALL LETTER T 1778 | ENCODING 116 1779 | SWIDTH 750 0 1780 | DWIDTH 6 0 1781 | BBX 6 8 0 -1 1782 | BITMAP 1783 | 40 1784 | 40 1785 | E0 1786 | 40 1787 | 40 1788 | 40 1789 | 30 1790 | 00 1791 | ENDCHAR 1792 | STARTCHAR LATIN SMALL LETTER U 1793 | ENCODING 117 1794 | SWIDTH 750 0 1795 | DWIDTH 6 0 1796 | BBX 6 8 0 -1 1797 | BITMAP 1798 | 00 1799 | 00 1800 | 90 1801 | 90 1802 | 90 1803 | 90 1804 | 70 1805 | 00 1806 | ENDCHAR 1807 | STARTCHAR LATIN SMALL LETTER V 1808 | ENCODING 118 1809 | SWIDTH 750 0 1810 | DWIDTH 6 0 1811 | BBX 6 8 0 -1 1812 | BITMAP 1813 | 00 1814 | 00 1815 | 90 1816 | 90 1817 | 90 1818 | 60 1819 | 60 1820 | 00 1821 | ENDCHAR 1822 | STARTCHAR LATIN SMALL LETTER W 1823 | ENCODING 119 1824 | SWIDTH 750 0 1825 | DWIDTH 6 0 1826 | BBX 6 8 0 -1 1827 | BITMAP 1828 | 00 1829 | 00 1830 | 90 1831 | 90 1832 | F0 1833 | F0 1834 | 90 1835 | 00 1836 | ENDCHAR 1837 | STARTCHAR LATIN SMALL LETTER X 1838 | ENCODING 120 1839 | SWIDTH 750 0 1840 | DWIDTH 6 0 1841 | BBX 6 8 0 -1 1842 | BITMAP 1843 | 00 1844 | 00 1845 | 90 1846 | 60 1847 | 60 1848 | 90 1849 | 90 1850 | 00 1851 | ENDCHAR 1852 | STARTCHAR LATIN SMALL LETTER Y 1853 | ENCODING 121 1854 | SWIDTH 750 0 1855 | DWIDTH 6 0 1856 | BBX 6 8 0 -1 1857 | BITMAP 1858 | 00 1859 | 00 1860 | 90 1861 | 90 1862 | 90 1863 | 70 1864 | 10 1865 | E0 1866 | ENDCHAR 1867 | STARTCHAR LATIN SMALL LETTER Z 1868 | ENCODING 122 1869 | SWIDTH 750 0 1870 | DWIDTH 6 0 1871 | BBX 6 8 0 -1 1872 | BITMAP 1873 | 00 1874 | 00 1875 | F0 1876 | 10 1877 | 20 1878 | 40 1879 | F0 1880 | 00 1881 | ENDCHAR 1882 | STARTCHAR LEFT CURLY BRACKET 1883 | ENCODING 123 1884 | SWIDTH 750 0 1885 | DWIDTH 6 0 1886 | BBX 6 8 0 -1 1887 | BITMAP 1888 | 30 1889 | 40 1890 | 40 1891 | C0 1892 | C0 1893 | 40 1894 | 40 1895 | 30 1896 | ENDCHAR 1897 | STARTCHAR VERTICAL LINE 1898 | ENCODING 124 1899 | SWIDTH 750 0 1900 | DWIDTH 6 0 1901 | BBX 6 8 0 -1 1902 | BITMAP 1903 | 00 1904 | 20 1905 | 20 1906 | 20 1907 | 20 1908 | 20 1909 | 20 1910 | 00 1911 | ENDCHAR 1912 | STARTCHAR RIGHT CURLY BRACKET 1913 | ENCODING 125 1914 | SWIDTH 750 0 1915 | DWIDTH 6 0 1916 | BBX 6 8 0 -1 1917 | BITMAP 1918 | C0 1919 | 20 1920 | 20 1921 | 30 1922 | 30 1923 | 20 1924 | 20 1925 | C0 1926 | ENDCHAR 1927 | STARTCHAR TILDE 1928 | ENCODING 126 1929 | SWIDTH 750 0 1930 | DWIDTH 6 0 1931 | BBX 6 8 0 -1 1932 | BITMAP 1933 | 00 1934 | 48 1935 | B0 1936 | 00 1937 | 00 1938 | 00 1939 | 00 1940 | 00 1941 | ENDCHAR 1942 | STARTCHAR 1943 | ENCODING 127 1944 | SWIDTH 750 0 1945 | DWIDTH 6 0 1946 | BBX 6 8 0 -1 1947 | BITMAP 1948 | 00 1949 | 00 1950 | 00 1951 | 00 1952 | 00 1953 | 00 1954 | 00 1955 | 00 1956 | ENDCHAR 1957 | STARTCHAR NO-BREAK SPACE 1958 | ENCODING 160 1959 | SWIDTH 750 0 1960 | DWIDTH 6 0 1961 | BBX 6 8 0 -1 1962 | BITMAP 1963 | 00 1964 | 00 1965 | 00 1966 | 00 1967 | 00 1968 | 00 1969 | 00 1970 | 00 1971 | ENDCHAR 1972 | STARTCHAR INVERTED EXCLAMATION MARK 1973 | ENCODING 161 1974 | SWIDTH 750 0 1975 | DWIDTH 6 0 1976 | BBX 6 8 0 -1 1977 | BITMAP 1978 | 00 1979 | 00 1980 | 00 1981 | 00 1982 | 00 1983 | 00 1984 | 00 1985 | 00 1986 | ENDCHAR 1987 | STARTCHAR CENT SIGN 1988 | ENCODING 162 1989 | SWIDTH 750 0 1990 | DWIDTH 6 0 1991 | BBX 6 8 0 -1 1992 | BITMAP 1993 | 00 1994 | 00 1995 | 00 1996 | 00 1997 | 00 1998 | 00 1999 | 00 2000 | 00 2001 | ENDCHAR 2002 | STARTCHAR POUND SIGN 2003 | ENCODING 163 2004 | SWIDTH 750 0 2005 | DWIDTH 6 0 2006 | BBX 6 8 0 -1 2007 | BITMAP 2008 | 00 2009 | 00 2010 | 00 2011 | 00 2012 | 00 2013 | 00 2014 | 00 2015 | 00 2016 | ENDCHAR 2017 | STARTCHAR CURRENCY SIGN 2018 | ENCODING 164 2019 | SWIDTH 750 0 2020 | DWIDTH 6 0 2021 | BBX 6 8 0 -1 2022 | BITMAP 2023 | 00 2024 | 00 2025 | 00 2026 | 00 2027 | 00 2028 | 00 2029 | 00 2030 | 00 2031 | ENDCHAR 2032 | STARTCHAR YEN SIGN 2033 | ENCODING 165 2034 | SWIDTH 750 0 2035 | DWIDTH 6 0 2036 | BBX 6 8 0 -1 2037 | BITMAP 2038 | 00 2039 | 00 2040 | 00 2041 | 00 2042 | 00 2043 | 00 2044 | 00 2045 | 00 2046 | ENDCHAR 2047 | STARTCHAR BROKEN BAR 2048 | ENCODING 166 2049 | SWIDTH 750 0 2050 | DWIDTH 6 0 2051 | BBX 6 8 0 -1 2052 | BITMAP 2053 | 00 2054 | 00 2055 | 00 2056 | 00 2057 | 00 2058 | 00 2059 | 00 2060 | 00 2061 | ENDCHAR 2062 | STARTCHAR SECTION SIGN 2063 | ENCODING 167 2064 | SWIDTH 750 0 2065 | DWIDTH 6 0 2066 | BBX 6 8 0 -1 2067 | BITMAP 2068 | 00 2069 | 00 2070 | 00 2071 | 00 2072 | 00 2073 | 00 2074 | 00 2075 | 00 2076 | ENDCHAR 2077 | STARTCHAR DIAERESIS 2078 | ENCODING 168 2079 | SWIDTH 750 0 2080 | DWIDTH 6 0 2081 | BBX 6 8 0 -1 2082 | BITMAP 2083 | 00 2084 | 00 2085 | 00 2086 | 00 2087 | 00 2088 | 00 2089 | 00 2090 | 00 2091 | ENDCHAR 2092 | STARTCHAR COPYRIGHT SIGN 2093 | ENCODING 169 2094 | SWIDTH 750 0 2095 | DWIDTH 6 0 2096 | BBX 6 8 0 -1 2097 | BITMAP 2098 | 00 2099 | 00 2100 | 00 2101 | 00 2102 | 00 2103 | 00 2104 | 00 2105 | 00 2106 | ENDCHAR 2107 | STARTCHAR FEMININE ORDINAL INDICATOR 2108 | ENCODING 170 2109 | SWIDTH 750 0 2110 | DWIDTH 6 0 2111 | BBX 6 8 0 -1 2112 | BITMAP 2113 | 00 2114 | 00 2115 | 00 2116 | 00 2117 | 00 2118 | 00 2119 | 00 2120 | 00 2121 | ENDCHAR 2122 | STARTCHAR LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 2123 | ENCODING 171 2124 | SWIDTH 750 0 2125 | DWIDTH 6 0 2126 | BBX 6 8 0 -1 2127 | BITMAP 2128 | 00 2129 | 00 2130 | 00 2131 | 00 2132 | 00 2133 | 00 2134 | 00 2135 | 00 2136 | ENDCHAR 2137 | STARTCHAR NOT SIGN 2138 | ENCODING 172 2139 | SWIDTH 750 0 2140 | DWIDTH 6 0 2141 | BBX 6 8 0 -1 2142 | BITMAP 2143 | 00 2144 | 00 2145 | 00 2146 | 00 2147 | 00 2148 | 00 2149 | 00 2150 | 00 2151 | ENDCHAR 2152 | STARTCHAR SOFT HYPHEN 2153 | ENCODING 173 2154 | SWIDTH 750 0 2155 | DWIDTH 6 0 2156 | BBX 6 8 0 -1 2157 | BITMAP 2158 | 00 2159 | 00 2160 | 00 2161 | 00 2162 | 00 2163 | 00 2164 | 00 2165 | 00 2166 | ENDCHAR 2167 | STARTCHAR REGISTERED SIGN 2168 | ENCODING 174 2169 | SWIDTH 750 0 2170 | DWIDTH 6 0 2171 | BBX 6 8 0 -1 2172 | BITMAP 2173 | 00 2174 | 00 2175 | 00 2176 | 00 2177 | 00 2178 | 00 2179 | 00 2180 | 00 2181 | ENDCHAR 2182 | STARTCHAR MACRON 2183 | ENCODING 175 2184 | SWIDTH 750 0 2185 | DWIDTH 6 0 2186 | BBX 6 8 0 -1 2187 | BITMAP 2188 | 00 2189 | 00 2190 | 00 2191 | 00 2192 | 00 2193 | 00 2194 | 00 2195 | 00 2196 | ENDCHAR 2197 | STARTCHAR DEGREE SIGN 2198 | ENCODING 176 2199 | SWIDTH 750 0 2200 | DWIDTH 6 0 2201 | BBX 6 8 0 -1 2202 | BITMAP 2203 | 00 2204 | A8 2205 | 00 2206 | A8 2207 | 00 2208 | A8 2209 | 00 2210 | A8 2211 | ENDCHAR 2212 | STARTCHAR PLUS-MINUS SIGN 2213 | ENCODING 177 2214 | SWIDTH 750 0 2215 | DWIDTH 6 0 2216 | BBX 6 8 0 -1 2217 | BITMAP 2218 | 50 2219 | A8 2220 | 50 2221 | A8 2222 | 50 2223 | A8 2224 | 50 2225 | A8 2226 | ENDCHAR 2227 | STARTCHAR SUPERSCRIPT TWO 2228 | ENCODING 178 2229 | SWIDTH 750 0 2230 | DWIDTH 6 0 2231 | BBX 6 8 0 -1 2232 | BITMAP 2233 | F8 2234 | 50 2235 | F8 2236 | 50 2237 | F8 2238 | 50 2239 | F8 2240 | 50 2241 | ENDCHAR 2242 | STARTCHAR SUPERSCRIPT THREE 2243 | ENCODING 179 2244 | SWIDTH 750 0 2245 | DWIDTH 6 0 2246 | BBX 6 8 0 -1 2247 | BITMAP 2248 | 20 2249 | 20 2250 | 20 2251 | 20 2252 | 20 2253 | 20 2254 | 20 2255 | 20 2256 | ENDCHAR 2257 | STARTCHAR ACUTE ACCENT 2258 | ENCODING 180 2259 | SWIDTH 750 0 2260 | DWIDTH 6 0 2261 | BBX 6 8 0 -1 2262 | BITMAP 2263 | 20 2264 | 20 2265 | 20 2266 | 20 2267 | E0 2268 | 20 2269 | 20 2270 | 20 2271 | ENDCHAR 2272 | STARTCHAR MICRO SIGN 2273 | ENCODING 181 2274 | SWIDTH 750 0 2275 | DWIDTH 6 0 2276 | BBX 6 8 0 -1 2277 | BITMAP 2278 | 20 2279 | 20 2280 | 20 2281 | E0 2282 | 20 2283 | E0 2284 | 20 2285 | 20 2286 | ENDCHAR 2287 | STARTCHAR PILCROW SIGN 2288 | ENCODING 182 2289 | SWIDTH 750 0 2290 | DWIDTH 6 0 2291 | BBX 6 8 0 -1 2292 | BITMAP 2293 | 50 2294 | 50 2295 | 50 2296 | 50 2297 | D0 2298 | 50 2299 | 50 2300 | 50 2301 | ENDCHAR 2302 | STARTCHAR MIDDLE DOT 2303 | ENCODING 183 2304 | SWIDTH 750 0 2305 | DWIDTH 6 0 2306 | BBX 6 8 0 -1 2307 | BITMAP 2308 | 00 2309 | 00 2310 | 00 2311 | 00 2312 | F0 2313 | 50 2314 | 50 2315 | 50 2316 | ENDCHAR 2317 | STARTCHAR CEDILLA 2318 | ENCODING 184 2319 | SWIDTH 750 0 2320 | DWIDTH 6 0 2321 | BBX 6 8 0 -1 2322 | BITMAP 2323 | 00 2324 | 00 2325 | 00 2326 | E0 2327 | 20 2328 | E0 2329 | 20 2330 | 20 2331 | ENDCHAR 2332 | STARTCHAR SUPERSCRIPT ONE 2333 | ENCODING 185 2334 | SWIDTH 750 0 2335 | DWIDTH 6 0 2336 | BBX 6 8 0 -1 2337 | BITMAP 2338 | 50 2339 | 50 2340 | 50 2341 | D0 2342 | 10 2343 | D0 2344 | 50 2345 | 50 2346 | ENDCHAR 2347 | STARTCHAR MASCULINE ORDINAL INDICATOR 2348 | ENCODING 186 2349 | SWIDTH 750 0 2350 | DWIDTH 6 0 2351 | BBX 6 8 0 -1 2352 | BITMAP 2353 | 50 2354 | 50 2355 | 50 2356 | 50 2357 | 50 2358 | 50 2359 | 50 2360 | 50 2361 | ENDCHAR 2362 | STARTCHAR RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 2363 | ENCODING 187 2364 | SWIDTH 750 0 2365 | DWIDTH 6 0 2366 | BBX 6 8 0 -1 2367 | BITMAP 2368 | 00 2369 | 00 2370 | 00 2371 | F0 2372 | 10 2373 | D0 2374 | 50 2375 | 50 2376 | ENDCHAR 2377 | STARTCHAR VULGAR FRACTION ONE QUARTER 2378 | ENCODING 188 2379 | SWIDTH 750 0 2380 | DWIDTH 6 0 2381 | BBX 6 8 0 -1 2382 | BITMAP 2383 | 50 2384 | 50 2385 | 50 2386 | D0 2387 | 10 2388 | F0 2389 | 00 2390 | 00 2391 | ENDCHAR 2392 | STARTCHAR VULGAR FRACTION ONE HALF 2393 | ENCODING 189 2394 | SWIDTH 750 0 2395 | DWIDTH 6 0 2396 | BBX 6 8 0 -1 2397 | BITMAP 2398 | 50 2399 | 50 2400 | 50 2401 | 50 2402 | F0 2403 | 00 2404 | 00 2405 | 00 2406 | ENDCHAR 2407 | STARTCHAR VULGAR FRACTION THREE QUARTERS 2408 | ENCODING 190 2409 | SWIDTH 750 0 2410 | DWIDTH 6 0 2411 | BBX 6 8 0 -1 2412 | BITMAP 2413 | 20 2414 | 20 2415 | 20 2416 | E0 2417 | 20 2418 | E0 2419 | 00 2420 | 00 2421 | ENDCHAR 2422 | STARTCHAR INVERTED QUESTION MARK 2423 | ENCODING 191 2424 | SWIDTH 750 0 2425 | DWIDTH 6 0 2426 | BBX 6 8 0 -1 2427 | BITMAP 2428 | 00 2429 | 00 2430 | 00 2431 | 00 2432 | E0 2433 | 20 2434 | 20 2435 | 20 2436 | ENDCHAR 2437 | STARTCHAR LATIN CAPITAL LETTER A WITH GRAVE 2438 | ENCODING 192 2439 | SWIDTH 750 0 2440 | DWIDTH 6 0 2441 | BBX 6 8 0 -1 2442 | BITMAP 2443 | 20 2444 | 20 2445 | 20 2446 | 20 2447 | 3C 2448 | 00 2449 | 00 2450 | 00 2451 | ENDCHAR 2452 | STARTCHAR LATIN CAPITAL LETTER A WITH ACUTE 2453 | ENCODING 193 2454 | SWIDTH 750 0 2455 | DWIDTH 6 0 2456 | BBX 6 8 0 -1 2457 | BITMAP 2458 | 20 2459 | 20 2460 | 20 2461 | 20 2462 | FC 2463 | 00 2464 | 00 2465 | 00 2466 | ENDCHAR 2467 | STARTCHAR LATIN CAPITAL LETTER A WITH CIRCUMFLEX 2468 | ENCODING 194 2469 | SWIDTH 750 0 2470 | DWIDTH 6 0 2471 | BBX 6 8 0 -1 2472 | BITMAP 2473 | 00 2474 | 00 2475 | 00 2476 | 00 2477 | FC 2478 | 20 2479 | 20 2480 | 20 2481 | ENDCHAR 2482 | STARTCHAR LATIN CAPITAL LETTER A WITH TILDE 2483 | ENCODING 195 2484 | SWIDTH 750 0 2485 | DWIDTH 6 0 2486 | BBX 6 8 0 -1 2487 | BITMAP 2488 | 20 2489 | 20 2490 | 20 2491 | 20 2492 | 3C 2493 | 20 2494 | 20 2495 | 20 2496 | ENDCHAR 2497 | STARTCHAR LATIN CAPITAL LETTER A WITH DIAERESIS 2498 | ENCODING 196 2499 | SWIDTH 750 0 2500 | DWIDTH 6 0 2501 | BBX 6 8 0 -1 2502 | BITMAP 2503 | 00 2504 | 00 2505 | 00 2506 | 00 2507 | FC 2508 | 00 2509 | 00 2510 | 00 2511 | ENDCHAR 2512 | STARTCHAR LATIN CAPITAL LETTER A WITH RING ABOVE 2513 | ENCODING 197 2514 | SWIDTH 750 0 2515 | DWIDTH 6 0 2516 | BBX 6 8 0 -1 2517 | BITMAP 2518 | 20 2519 | 20 2520 | 20 2521 | 20 2522 | FC 2523 | 20 2524 | 20 2525 | 20 2526 | ENDCHAR 2527 | STARTCHAR LATIN CAPITAL LETTER AE 2528 | ENCODING 198 2529 | SWIDTH 750 0 2530 | DWIDTH 6 0 2531 | BBX 6 8 0 -1 2532 | BITMAP 2533 | 20 2534 | 20 2535 | 20 2536 | 3C 2537 | 20 2538 | 3C 2539 | 20 2540 | 20 2541 | ENDCHAR 2542 | STARTCHAR LATIN CAPITAL LETTER C WITH CEDILLA 2543 | ENCODING 199 2544 | SWIDTH 750 0 2545 | DWIDTH 6 0 2546 | BBX 6 8 0 -1 2547 | BITMAP 2548 | 50 2549 | 50 2550 | 50 2551 | 50 2552 | 5C 2553 | 50 2554 | 50 2555 | 50 2556 | ENDCHAR 2557 | STARTCHAR LATIN CAPITAL LETTER E WITH GRAVE 2558 | ENCODING 200 2559 | SWIDTH 750 0 2560 | DWIDTH 6 0 2561 | BBX 6 8 0 -1 2562 | BITMAP 2563 | 50 2564 | 50 2565 | 50 2566 | 5C 2567 | 40 2568 | 7C 2569 | 00 2570 | 00 2571 | ENDCHAR 2572 | STARTCHAR LATIN CAPITAL LETTER E WITH ACUTE 2573 | ENCODING 201 2574 | SWIDTH 750 0 2575 | DWIDTH 6 0 2576 | BBX 6 8 0 -1 2577 | BITMAP 2578 | 00 2579 | 00 2580 | 00 2581 | 7C 2582 | 40 2583 | 5C 2584 | 50 2585 | 50 2586 | ENDCHAR 2587 | STARTCHAR LATIN CAPITAL LETTER E WITH CIRCUMFLEX 2588 | ENCODING 202 2589 | SWIDTH 750 0 2590 | DWIDTH 6 0 2591 | BBX 6 8 0 -1 2592 | BITMAP 2593 | 50 2594 | 50 2595 | 50 2596 | DC 2597 | 00 2598 | FC 2599 | 00 2600 | 00 2601 | ENDCHAR 2602 | STARTCHAR LATIN CAPITAL LETTER E WITH DIAERESIS 2603 | ENCODING 203 2604 | SWIDTH 750 0 2605 | DWIDTH 6 0 2606 | BBX 6 8 0 -1 2607 | BITMAP 2608 | 00 2609 | 00 2610 | 00 2611 | FC 2612 | 00 2613 | DC 2614 | 50 2615 | 50 2616 | ENDCHAR 2617 | STARTCHAR LATIN CAPITAL LETTER I WITH GRAVE 2618 | ENCODING 204 2619 | SWIDTH 750 0 2620 | DWIDTH 6 0 2621 | BBX 6 8 0 -1 2622 | BITMAP 2623 | 50 2624 | 50 2625 | 50 2626 | 5C 2627 | 40 2628 | 5C 2629 | 50 2630 | 50 2631 | ENDCHAR 2632 | STARTCHAR LATIN CAPITAL LETTER I WITH ACUTE 2633 | ENCODING 205 2634 | SWIDTH 750 0 2635 | DWIDTH 6 0 2636 | BBX 6 8 0 -1 2637 | BITMAP 2638 | 00 2639 | 00 2640 | 00 2641 | FC 2642 | 00 2643 | FC 2644 | 00 2645 | 00 2646 | ENDCHAR 2647 | STARTCHAR LATIN CAPITAL LETTER I WITH CIRCUMFLEX 2648 | ENCODING 206 2649 | SWIDTH 750 0 2650 | DWIDTH 6 0 2651 | BBX 6 8 0 -1 2652 | BITMAP 2653 | 50 2654 | 50 2655 | 50 2656 | DC 2657 | 00 2658 | DC 2659 | 50 2660 | 50 2661 | ENDCHAR 2662 | STARTCHAR LATIN CAPITAL LETTER I WITH DIAERESIS 2663 | ENCODING 207 2664 | SWIDTH 750 0 2665 | DWIDTH 6 0 2666 | BBX 6 8 0 -1 2667 | BITMAP 2668 | 20 2669 | 20 2670 | 20 2671 | FC 2672 | 00 2673 | FC 2674 | 00 2675 | 00 2676 | ENDCHAR 2677 | STARTCHAR LATIN CAPITAL LETTER ETH 2678 | ENCODING 208 2679 | SWIDTH 750 0 2680 | DWIDTH 6 0 2681 | BBX 6 8 0 -1 2682 | BITMAP 2683 | 50 2684 | 50 2685 | 50 2686 | FC 2687 | 00 2688 | FC 2689 | 00 2690 | 00 2691 | ENDCHAR 2692 | STARTCHAR LATIN CAPITAL LETTER N WITH TILDE 2693 | ENCODING 209 2694 | SWIDTH 750 0 2695 | DWIDTH 6 0 2696 | BBX 6 8 0 -1 2697 | BITMAP 2698 | 00 2699 | 00 2700 | 00 2701 | FC 2702 | 00 2703 | FC 2704 | 20 2705 | 20 2706 | ENDCHAR 2707 | STARTCHAR LATIN CAPITAL LETTER O WITH GRAVE 2708 | ENCODING 210 2709 | SWIDTH 750 0 2710 | DWIDTH 6 0 2711 | BBX 6 8 0 -1 2712 | BITMAP 2713 | 00 2714 | 00 2715 | 00 2716 | 00 2717 | FC 2718 | 50 2719 | 50 2720 | 50 2721 | ENDCHAR 2722 | STARTCHAR LATIN CAPITAL LETTER O WITH ACUTE 2723 | ENCODING 211 2724 | SWIDTH 750 0 2725 | DWIDTH 6 0 2726 | BBX 6 8 0 -1 2727 | BITMAP 2728 | 50 2729 | 50 2730 | 50 2731 | 50 2732 | FC 2733 | 00 2734 | 00 2735 | 00 2736 | ENDCHAR 2737 | STARTCHAR LATIN CAPITAL LETTER O WITH CIRCUMFLEX 2738 | ENCODING 212 2739 | SWIDTH 750 0 2740 | DWIDTH 6 0 2741 | BBX 6 8 0 -1 2742 | BITMAP 2743 | 20 2744 | 20 2745 | 20 2746 | 3C 2747 | 20 2748 | 3C 2749 | 00 2750 | 00 2751 | ENDCHAR 2752 | STARTCHAR LATIN CAPITAL LETTER O WITH TILDE 2753 | ENCODING 213 2754 | SWIDTH 750 0 2755 | DWIDTH 6 0 2756 | BBX 6 8 0 -1 2757 | BITMAP 2758 | 00 2759 | 00 2760 | 00 2761 | 3C 2762 | 20 2763 | 3C 2764 | 20 2765 | 20 2766 | ENDCHAR 2767 | STARTCHAR LATIN CAPITAL LETTER O WITH DIAERESIS 2768 | ENCODING 214 2769 | SWIDTH 750 0 2770 | DWIDTH 6 0 2771 | BBX 6 8 0 -1 2772 | BITMAP 2773 | 00 2774 | 00 2775 | 00 2776 | 00 2777 | 7C 2778 | 50 2779 | 50 2780 | 50 2781 | ENDCHAR 2782 | STARTCHAR MULTIPLICATION SIGN 2783 | ENCODING 215 2784 | SWIDTH 750 0 2785 | DWIDTH 6 0 2786 | BBX 6 8 0 -1 2787 | BITMAP 2788 | 50 2789 | 50 2790 | 50 2791 | 50 2792 | FC 2793 | 50 2794 | 50 2795 | 50 2796 | ENDCHAR 2797 | STARTCHAR LATIN CAPITAL LETTER O WITH STROKE 2798 | ENCODING 216 2799 | SWIDTH 750 0 2800 | DWIDTH 6 0 2801 | BBX 6 8 0 -1 2802 | BITMAP 2803 | 20 2804 | 20 2805 | 20 2806 | FC 2807 | 00 2808 | FC 2809 | 20 2810 | 20 2811 | ENDCHAR 2812 | STARTCHAR LATIN CAPITAL LETTER U WITH GRAVE 2813 | ENCODING 217 2814 | SWIDTH 750 0 2815 | DWIDTH 6 0 2816 | BBX 6 8 0 -1 2817 | BITMAP 2818 | 20 2819 | 20 2820 | 20 2821 | 20 2822 | E0 2823 | 00 2824 | 00 2825 | 00 2826 | ENDCHAR 2827 | STARTCHAR LATIN CAPITAL LETTER U WITH ACUTE 2828 | ENCODING 218 2829 | SWIDTH 750 0 2830 | DWIDTH 6 0 2831 | BBX 6 8 0 -1 2832 | BITMAP 2833 | 00 2834 | 00 2835 | 00 2836 | 00 2837 | 3C 2838 | 20 2839 | 20 2840 | 20 2841 | ENDCHAR 2842 | STARTCHAR LATIN CAPITAL LETTER U WITH CIRCUMFLEX 2843 | ENCODING 219 2844 | SWIDTH 750 0 2845 | DWIDTH 6 0 2846 | BBX 6 8 0 -1 2847 | BITMAP 2848 | F8 2849 | F8 2850 | F8 2851 | F8 2852 | F8 2853 | F8 2854 | F8 2855 | F8 2856 | ENDCHAR 2857 | STARTCHAR LATIN CAPITAL LETTER U WITH DIAERESIS 2858 | ENCODING 220 2859 | SWIDTH 750 0 2860 | DWIDTH 6 0 2861 | BBX 6 8 0 -1 2862 | BITMAP 2863 | 00 2864 | 00 2865 | 00 2866 | F8 2867 | F8 2868 | F8 2869 | F8 2870 | F8 2871 | ENDCHAR 2872 | STARTCHAR LATIN CAPITAL LETTER Y WITH ACUTE 2873 | ENCODING 221 2874 | SWIDTH 750 0 2875 | DWIDTH 6 0 2876 | BBX 6 8 0 -1 2877 | BITMAP 2878 | E0 2879 | E0 2880 | E0 2881 | E0 2882 | E0 2883 | E0 2884 | E0 2885 | E0 2886 | ENDCHAR 2887 | STARTCHAR LATIN CAPITAL LETTER THORN 2888 | ENCODING 222 2889 | SWIDTH 750 0 2890 | DWIDTH 6 0 2891 | BBX 6 8 0 -1 2892 | BITMAP 2893 | 38 2894 | 38 2895 | 38 2896 | 38 2897 | 38 2898 | 38 2899 | 38 2900 | 38 2901 | ENDCHAR 2902 | STARTCHAR LATIN SMALL LETTER SHARP S 2903 | ENCODING 223 2904 | SWIDTH 750 0 2905 | DWIDTH 6 0 2906 | BBX 6 8 0 -1 2907 | BITMAP 2908 | F8 2909 | F8 2910 | F8 2911 | F8 2912 | 00 2913 | 00 2914 | 00 2915 | 00 2916 | ENDCHAR 2917 | STARTCHAR LATIN SMALL LETTER A WITH GRAVE 2918 | ENCODING 224 2919 | SWIDTH 750 0 2920 | DWIDTH 6 0 2921 | BBX 6 8 0 -1 2922 | BITMAP 2923 | 00 2924 | 00 2925 | 00 2926 | 00 2927 | 00 2928 | 00 2929 | 00 2930 | 00 2931 | ENDCHAR 2932 | STARTCHAR LATIN SMALL LETTER A WITH ACUTE 2933 | ENCODING 225 2934 | SWIDTH 750 0 2935 | DWIDTH 6 0 2936 | BBX 6 8 0 -1 2937 | BITMAP 2938 | 00 2939 | 00 2940 | 00 2941 | 00 2942 | 00 2943 | 00 2944 | 00 2945 | 00 2946 | ENDCHAR 2947 | STARTCHAR LATIN SMALL LETTER A WITH CIRCUMFLEX 2948 | ENCODING 226 2949 | SWIDTH 750 0 2950 | DWIDTH 6 0 2951 | BBX 6 8 0 -1 2952 | BITMAP 2953 | 00 2954 | 00 2955 | 00 2956 | 00 2957 | 00 2958 | 00 2959 | 00 2960 | 00 2961 | ENDCHAR 2962 | STARTCHAR LATIN SMALL LETTER A WITH TILDE 2963 | ENCODING 227 2964 | SWIDTH 750 0 2965 | DWIDTH 6 0 2966 | BBX 6 8 0 -1 2967 | BITMAP 2968 | 00 2969 | 00 2970 | 00 2971 | 00 2972 | 00 2973 | 00 2974 | 00 2975 | 00 2976 | ENDCHAR 2977 | STARTCHAR LATIN SMALL LETTER A WITH DIAERESIS 2978 | ENCODING 228 2979 | SWIDTH 750 0 2980 | DWIDTH 6 0 2981 | BBX 6 8 0 -1 2982 | BITMAP 2983 | 00 2984 | 00 2985 | 00 2986 | 00 2987 | 00 2988 | 00 2989 | 00 2990 | 00 2991 | ENDCHAR 2992 | STARTCHAR LATIN SMALL LETTER A WITH RING ABOVE 2993 | ENCODING 229 2994 | SWIDTH 750 0 2995 | DWIDTH 6 0 2996 | BBX 6 8 0 -1 2997 | BITMAP 2998 | 00 2999 | 00 3000 | 00 3001 | 00 3002 | 00 3003 | 00 3004 | 00 3005 | 00 3006 | ENDCHAR 3007 | STARTCHAR LATIN SMALL LETTER AE 3008 | ENCODING 230 3009 | SWIDTH 750 0 3010 | DWIDTH 6 0 3011 | BBX 6 8 0 -1 3012 | BITMAP 3013 | 00 3014 | 00 3015 | 00 3016 | 00 3017 | 00 3018 | 00 3019 | 00 3020 | 00 3021 | ENDCHAR 3022 | STARTCHAR LATIN SMALL LETTER C WITH CEDILLA 3023 | ENCODING 231 3024 | SWIDTH 750 0 3025 | DWIDTH 6 0 3026 | BBX 6 8 0 -1 3027 | BITMAP 3028 | 00 3029 | 00 3030 | 00 3031 | 00 3032 | 00 3033 | 00 3034 | 00 3035 | 00 3036 | ENDCHAR 3037 | STARTCHAR LATIN SMALL LETTER E WITH GRAVE 3038 | ENCODING 232 3039 | SWIDTH 750 0 3040 | DWIDTH 6 0 3041 | BBX 6 8 0 -1 3042 | BITMAP 3043 | 00 3044 | 00 3045 | 00 3046 | 00 3047 | 00 3048 | 00 3049 | 00 3050 | 00 3051 | ENDCHAR 3052 | STARTCHAR LATIN SMALL LETTER E WITH ACUTE 3053 | ENCODING 233 3054 | SWIDTH 750 0 3055 | DWIDTH 6 0 3056 | BBX 6 8 0 -1 3057 | BITMAP 3058 | 00 3059 | 00 3060 | 00 3061 | 00 3062 | 00 3063 | 00 3064 | 00 3065 | 00 3066 | ENDCHAR 3067 | STARTCHAR LATIN SMALL LETTER E WITH CIRCUMFLEX 3068 | ENCODING 234 3069 | SWIDTH 750 0 3070 | DWIDTH 6 0 3071 | BBX 6 8 0 -1 3072 | BITMAP 3073 | 00 3074 | 00 3075 | 00 3076 | 00 3077 | 00 3078 | 00 3079 | 00 3080 | 00 3081 | ENDCHAR 3082 | STARTCHAR LATIN SMALL LETTER E WITH DIAERESIS 3083 | ENCODING 235 3084 | SWIDTH 750 0 3085 | DWIDTH 6 0 3086 | BBX 6 8 0 -1 3087 | BITMAP 3088 | 00 3089 | 00 3090 | 00 3091 | 00 3092 | 00 3093 | 00 3094 | 00 3095 | 00 3096 | ENDCHAR 3097 | STARTCHAR LATIN SMALL LETTER I WITH GRAVE 3098 | ENCODING 236 3099 | SWIDTH 750 0 3100 | DWIDTH 6 0 3101 | BBX 6 8 0 -1 3102 | BITMAP 3103 | 00 3104 | 00 3105 | 00 3106 | 00 3107 | 00 3108 | 00 3109 | 00 3110 | 00 3111 | ENDCHAR 3112 | STARTCHAR LATIN SMALL LETTER I WITH ACUTE 3113 | ENCODING 237 3114 | SWIDTH 750 0 3115 | DWIDTH 6 0 3116 | BBX 6 8 0 -1 3117 | BITMAP 3118 | 00 3119 | 00 3120 | 00 3121 | 00 3122 | 00 3123 | 00 3124 | 00 3125 | 00 3126 | ENDCHAR 3127 | STARTCHAR LATIN SMALL LETTER I WITH CIRCUMFLEX 3128 | ENCODING 238 3129 | SWIDTH 750 0 3130 | DWIDTH 6 0 3131 | BBX 6 8 0 -1 3132 | BITMAP 3133 | 00 3134 | 00 3135 | 00 3136 | 00 3137 | 00 3138 | 00 3139 | 00 3140 | 00 3141 | ENDCHAR 3142 | STARTCHAR LATIN SMALL LETTER I WITH DIAERESIS 3143 | ENCODING 239 3144 | SWIDTH 750 0 3145 | DWIDTH 6 0 3146 | BBX 6 8 0 -1 3147 | BITMAP 3148 | 00 3149 | 00 3150 | 00 3151 | 00 3152 | 00 3153 | 00 3154 | 00 3155 | 00 3156 | ENDCHAR 3157 | STARTCHAR LATIN SMALL LETTER ETH 3158 | ENCODING 240 3159 | SWIDTH 750 0 3160 | DWIDTH 6 0 3161 | BBX 6 8 0 -1 3162 | BITMAP 3163 | 00 3164 | 00 3165 | 00 3166 | 00 3167 | 00 3168 | 00 3169 | 00 3170 | 00 3171 | ENDCHAR 3172 | STARTCHAR LATIN SMALL LETTER N WITH TILDE 3173 | ENCODING 241 3174 | SWIDTH 750 0 3175 | DWIDTH 6 0 3176 | BBX 6 8 0 -1 3177 | BITMAP 3178 | 00 3179 | 00 3180 | 00 3181 | 00 3182 | 00 3183 | 00 3184 | 00 3185 | 00 3186 | ENDCHAR 3187 | STARTCHAR LATIN SMALL LETTER O WITH GRAVE 3188 | ENCODING 242 3189 | SWIDTH 750 0 3190 | DWIDTH 6 0 3191 | BBX 6 8 0 -1 3192 | BITMAP 3193 | 00 3194 | 00 3195 | 00 3196 | 00 3197 | 00 3198 | 00 3199 | 00 3200 | 00 3201 | ENDCHAR 3202 | STARTCHAR LATIN SMALL LETTER O WITH ACUTE 3203 | ENCODING 243 3204 | SWIDTH 750 0 3205 | DWIDTH 6 0 3206 | BBX 6 8 0 -1 3207 | BITMAP 3208 | 00 3209 | 00 3210 | 00 3211 | 00 3212 | 00 3213 | 00 3214 | 00 3215 | 00 3216 | ENDCHAR 3217 | STARTCHAR LATIN SMALL LETTER O WITH CIRCUMFLEX 3218 | ENCODING 244 3219 | SWIDTH 750 0 3220 | DWIDTH 6 0 3221 | BBX 6 8 0 -1 3222 | BITMAP 3223 | 00 3224 | 00 3225 | 00 3226 | 00 3227 | 00 3228 | 00 3229 | 00 3230 | 00 3231 | ENDCHAR 3232 | STARTCHAR LATIN SMALL LETTER O WITH TILDE 3233 | ENCODING 245 3234 | SWIDTH 750 0 3235 | DWIDTH 6 0 3236 | BBX 6 8 0 -1 3237 | BITMAP 3238 | 00 3239 | 00 3240 | 00 3241 | 00 3242 | 00 3243 | 00 3244 | 00 3245 | 00 3246 | ENDCHAR 3247 | STARTCHAR LATIN SMALL LETTER O WITH DIAERESIS 3248 | ENCODING 246 3249 | SWIDTH 750 0 3250 | DWIDTH 6 0 3251 | BBX 6 8 0 -1 3252 | BITMAP 3253 | 00 3254 | 00 3255 | 00 3256 | 00 3257 | 00 3258 | 00 3259 | 00 3260 | 00 3261 | ENDCHAR 3262 | STARTCHAR DIVISION SIGN 3263 | ENCODING 247 3264 | SWIDTH 750 0 3265 | DWIDTH 6 0 3266 | BBX 6 8 0 -1 3267 | BITMAP 3268 | 00 3269 | 00 3270 | 00 3271 | 00 3272 | 00 3273 | 00 3274 | 00 3275 | 00 3276 | ENDCHAR 3277 | STARTCHAR LATIN SMALL LETTER O WITH STROKE 3278 | ENCODING 248 3279 | SWIDTH 750 0 3280 | DWIDTH 6 0 3281 | BBX 6 8 0 -1 3282 | BITMAP 3283 | 00 3284 | 00 3285 | 00 3286 | 00 3287 | 00 3288 | 00 3289 | 00 3290 | 00 3291 | ENDCHAR 3292 | STARTCHAR LATIN SMALL LETTER U WITH GRAVE 3293 | ENCODING 249 3294 | SWIDTH 750 0 3295 | DWIDTH 6 0 3296 | BBX 6 8 0 -1 3297 | BITMAP 3298 | 00 3299 | 00 3300 | 00 3301 | 00 3302 | 00 3303 | 00 3304 | 00 3305 | 00 3306 | ENDCHAR 3307 | STARTCHAR LATIN SMALL LETTER U WITH ACUTE 3308 | ENCODING 250 3309 | SWIDTH 750 0 3310 | DWIDTH 6 0 3311 | BBX 6 8 0 -1 3312 | BITMAP 3313 | 00 3314 | 00 3315 | 00 3316 | 00 3317 | 00 3318 | 00 3319 | 00 3320 | 00 3321 | ENDCHAR 3322 | STARTCHAR LATIN SMALL LETTER U WITH CIRCUMFLEX 3323 | ENCODING 251 3324 | SWIDTH 750 0 3325 | DWIDTH 6 0 3326 | BBX 6 8 0 -1 3327 | BITMAP 3328 | 00 3329 | 00 3330 | 00 3331 | 00 3332 | 00 3333 | 00 3334 | 00 3335 | 00 3336 | ENDCHAR 3337 | STARTCHAR LATIN SMALL LETTER U WITH DIAERESIS 3338 | ENCODING 252 3339 | SWIDTH 750 0 3340 | DWIDTH 6 0 3341 | BBX 6 8 0 -1 3342 | BITMAP 3343 | 00 3344 | 00 3345 | 00 3346 | 00 3347 | 00 3348 | 00 3349 | 00 3350 | 00 3351 | ENDCHAR 3352 | STARTCHAR LATIN SMALL LETTER Y WITH ACUTE 3353 | ENCODING 253 3354 | SWIDTH 750 0 3355 | DWIDTH 6 0 3356 | BBX 6 8 0 -1 3357 | BITMAP 3358 | 70 3359 | 10 3360 | 20 3361 | 70 3362 | 00 3363 | 00 3364 | 00 3365 | 00 3366 | ENDCHAR 3367 | STARTCHAR LATIN SMALL LETTER THORN 3368 | ENCODING 254 3369 | SWIDTH 750 0 3370 | DWIDTH 6 0 3371 | BBX 6 8 0 -1 3372 | BITMAP 3373 | 00 3374 | 00 3375 | F0 3376 | F0 3377 | F0 3378 | F0 3379 | 00 3380 | 00 3381 | ENDCHAR 3382 | STARTCHAR LATIN SMALL LETTER Y WITH DIAERESIS 3383 | ENCODING 255 3384 | SWIDTH 750 0 3385 | DWIDTH 6 0 3386 | BBX 6 8 0 -1 3387 | BITMAP 3388 | 00 3389 | 00 3390 | 00 3391 | 00 3392 | 00 3393 | 00 3394 | 00 3395 | 00 3396 | ENDCHAR 3397 | ENDFONT 3398 | -------------------------------------------------------------------------------- /lib/font/spleen-5x8.hex: -------------------------------------------------------------------------------- 1 | 0000:F8D8A8E8D8F8D8F8 2 | 0001:7088D888F8887000 3 | 0002:70F8A8F888F87000 4 | 0003:0050F8F870200000 5 | 0004:002070F870200000 6 | 0005:002070D8D8207000 7 | 0006:002070F8F8207000 8 | 0007:0000207070200000 9 | 0008:7070500050707070 10 | 0009:0000205050200000 11 | 000A:7070502020507070 12 | 000B:0030709090600000 13 | 000C:0020505020702000 14 | 000D:00383820E0C00000 15 | 000E:0038382828500000 16 | 000F:00A870D870A80000 17 | 0010:0040607070604000 18 | 0011:0010307070301000 19 | 0012:0020702070200000 20 | 0013:0050505050005000 21 | 0014:0070D0D050500000 22 | 0015:609060F070906000 23 | 0016:0000000000F8F800 24 | 0017:2070202070207000 25 | 0018:2070202020200000 26 | 0019:2020202070200000 27 | 001A:000020F020000000 28 | 001B:000040F040000000 29 | 001C:00008080F8000000 30 | 001D:000050F850000000 31 | 001E:00002070F8000000 32 | 001F:0000F87020000000 33 | 0020:0000000000000000 34 | 0021:2020202020002000 35 | 0022:5050500000000000 36 | 0023:0050F85050F85000 37 | 0024:2070A0603030E020 38 | 0025:1090A02040509080 39 | 0026:20505060A0906800 40 | 0027:2020200000000000 41 | 0028:1020404040402010 42 | 0029:4020101010102040 43 | 002A:00009060F0609000 44 | 002B:00002020F8202000 45 | 002C:0000000000202040 46 | 002D:00000000F0000000 47 | 002E:0000000000002000 48 | 002F:1010202040408080 49 | 0030:006090B0D0906000 50 | 0031:0020602020207000 51 | 0032:006090106080F000 52 | 0033:0060902010906000 53 | 0034:0080A0A0F0202000 54 | 0035:00F080F01010E000 55 | 0036:006080E090906000 56 | 0037:00F0902020404000 57 | 0038:0060906090906000 58 | 0039:0060909070106000 59 | 003A:0000002000002000 60 | 003B:0000002000202040 61 | 003C:0010204040201000 62 | 003D:000000F000F00000 63 | 003E:0040201010204000 64 | 003F:6090102040004000 65 | 0040:006090B0B0807000 66 | 0041:00609090F0909000 67 | 0042:00E090E09090E000 68 | 0043:0070808080807000 69 | 0044:00E090909090E000 70 | 0045:007080E080807000 71 | 0046:00708080E0808000 72 | 0047:007080B090907000 73 | 0048:009090F090909000 74 | 0049:0070202020207000 75 | 004A:007020202020C000 76 | 004B:009090E090909000 77 | 004C:0080808080807000 78 | 004D:0090F0F090909000 79 | 004E:0090D0D0B0B09000 80 | 004F:0060909090906000 81 | 0050:00E09090E0808000 82 | 0051:0060909090906030 83 | 0052:00E09090E0909000 84 | 0053:007080601010E000 85 | 0054:00F8202020202000 86 | 0055:0090909090907000 87 | 0056:0090909090606000 88 | 0057:00909090F0F09000 89 | 0058:0090906060909000 90 | 0059:009090907010E000 91 | 005A:00F010204080F000 92 | 005B:7040404040404070 93 | 005C:8080404020201010 94 | 005D:7010101010101070 95 | 005E:0020508800000000 96 | 005F:00000000000000F0 97 | 0060:4020000000000000 98 | 0061:0000601070907000 99 | 0062:8080E0909090E000 100 | 0063:0000708080807000 101 | 0064:1010709090907000 102 | 0065:00007090F0807000 103 | 0066:304040E040404000 104 | 0067:00007090906010E0 105 | 0068:8080E09090909000 106 | 0069:0020002020202000 107 | 006A:00200020202020C0 108 | 006B:808090A0C0A09000 109 | 006C:4040404040403000 110 | 006D:000090F0F0909000 111 | 006E:0000E09090909000 112 | 006F:0000609090906000 113 | 0070:0000E09090E08080 114 | 0071:0000709090701010 115 | 0072:0000709080808000 116 | 0073:000070806010E000 117 | 0074:4040E04040403000 118 | 0075:0000909090907000 119 | 0076:0000909090606000 120 | 0077:00009090F0F09000 121 | 0078:0000906060909000 122 | 0079:00009090907010E0 123 | 007A:0000F0102040F000 124 | 007B:304040C0C0404030 125 | 007C:0020202020202000 126 | 007D:C0202030302020C0 127 | 007E:0048B00000000000 128 | 007F:0000000000000000 129 | 00A0:0000000000000000 130 | 00A1:0000000000000000 131 | 00A2:0000000000000000 132 | 00A3:0000000000000000 133 | 00A4:0000000000000000 134 | 00A5:0000000000000000 135 | 00A6:0000000000000000 136 | 00A7:0000000000000000 137 | 00A8:0000000000000000 138 | 00A9:0000000000000000 139 | 00AA:0000000000000000 140 | 00AB:0000000000000000 141 | 00AC:0000000000000000 142 | 00AD:0000000000000000 143 | 00AE:0000000000000000 144 | 00AF:0000000000000000 145 | 00B0:00A800A800A800A8 146 | 00B1:50A850A850A850A8 147 | 00B2:F850F850F850F850 148 | 00B3:2020202020202020 149 | 00B4:20202020E0202020 150 | 00B5:202020E020E02020 151 | 00B6:50505050D0505050 152 | 00B7:00000000F0505050 153 | 00B8:000000E020E02020 154 | 00B9:505050D010D05050 155 | 00BA:5050505050505050 156 | 00BB:000000F010D05050 157 | 00BC:505050D010F00000 158 | 00BD:50505050F0000000 159 | 00BE:202020E020E00000 160 | 00BF:00000000E0202020 161 | 00C0:202020203C000000 162 | 00C1:20202020FC000000 163 | 00C2:00000000FC202020 164 | 00C3:202020203C202020 165 | 00C4:00000000FC000000 166 | 00C5:20202020FC202020 167 | 00C6:2020203C203C2020 168 | 00C7:505050505C505050 169 | 00C8:5050505C407C0000 170 | 00C9:0000007C405C5050 171 | 00CA:505050DC00FC0000 172 | 00CB:000000FC00DC5050 173 | 00CC:5050505C405C5050 174 | 00CD:000000FC00FC0000 175 | 00CE:505050DC00DC5050 176 | 00CF:202020FC00FC0000 177 | 00D0:505050FC00FC0000 178 | 00D1:000000FC00FC2020 179 | 00D2:00000000FC505050 180 | 00D3:50505050FC000000 181 | 00D4:2020203C203C0000 182 | 00D5:0000003C203C2020 183 | 00D6:000000007C505050 184 | 00D7:50505050FC505050 185 | 00D8:202020FC00FC2020 186 | 00D9:20202020E0000000 187 | 00DA:000000003C202020 188 | 00DB:F8F8F8F8F8F8F8F8 189 | 00DC:000000F8F8F8F8F8 190 | 00DD:E0E0E0E0E0E0E0E0 191 | 00DE:3838383838383838 192 | 00DF:F8F8F8F800000000 193 | 00E0:0000000000000000 194 | 00E1:0000000000000000 195 | 00E2:0000000000000000 196 | 00E3:0000000000000000 197 | 00E4:0000000000000000 198 | 00E5:0000000000000000 199 | 00E6:0000000000000000 200 | 00E7:0000000000000000 201 | 00E8:0000000000000000 202 | 00E9:0000000000000000 203 | 00EA:0000000000000000 204 | 00EB:0000000000000000 205 | 00EC:0000000000000000 206 | 00ED:0000000000000000 207 | 00EE:0000000000000000 208 | 00EF:0000000000000000 209 | 00F0:0000000000000000 210 | 00F1:0000000000000000 211 | 00F2:0000000000000000 212 | 00F3:0000000000000000 213 | 00F4:0000000000000000 214 | 00F5:0000000000000000 215 | 00F6:0000000000000000 216 | 00F7:0000000000000000 217 | 00F8:0000000000000000 218 | 00F9:0000000000000000 219 | 00FA:0000000000000000 220 | 00FB:0000000000000000 221 | 00FC:0000000000000000 222 | 00FD:7010207000000000 223 | 00FE:0000F0F0F0F00000 224 | 00FF:0000000000000000 225 | -------------------------------------------------------------------------------- /lib/font/spleen-5x8.inc: -------------------------------------------------------------------------------- 1 | .db #0x1f, #0x1b, #0x15, #0x17, #0x1b, #0x1f, #0x1b, #0x1f 2 | .db #0x0e, #0x11, #0x1b, #0x11, #0x1f, #0x11, #0x0e, #0x00 3 | .db #0x0e, #0x1f, #0x15, #0x1f, #0x11, #0x1f, #0x0e, #0x00 4 | .db #0x00, #0x0a, #0x1f, #0x1f, #0x0e, #0x04, #0x00, #0x00 5 | .db #0x00, #0x04, #0x0e, #0x1f, #0x0e, #0x04, #0x00, #0x00 6 | .db #0x00, #0x04, #0x0e, #0x1b, #0x1b, #0x04, #0x0e, #0x00 7 | .db #0x00, #0x04, #0x0e, #0x1f, #0x1f, #0x04, #0x0e, #0x00 8 | .db #0x00, #0x00, #0x04, #0x0e, #0x0e, #0x04, #0x00, #0x00 9 | .db #0x0e, #0x0e, #0x0a, #0x00, #0x0a, #0x0e, #0x0e, #0x0e 10 | .db #0x00, #0x00, #0x04, #0x0a, #0x0a, #0x04, #0x00, #0x00 11 | .db #0x0e, #0x0e, #0x0a, #0x04, #0x04, #0x0a, #0x0e, #0x0e 12 | .db #0x00, #0x0c, #0x0e, #0x09, #0x09, #0x06, #0x00, #0x00 13 | .db #0x00, #0x04, #0x0a, #0x0a, #0x04, #0x0e, #0x04, #0x00 14 | .db #0x00, #0x1c, #0x1c, #0x04, #0x07, #0x03, #0x00, #0x00 15 | .db #0x00, #0x1c, #0x1c, #0x14, #0x14, #0x0a, #0x00, #0x00 16 | .db #0x00, #0x15, #0x0e, #0x1b, #0x0e, #0x15, #0x00, #0x00 17 | .db #0x00, #0x02, #0x06, #0x0e, #0x0e, #0x06, #0x02, #0x00 18 | .db #0x00, #0x08, #0x0c, #0x0e, #0x0e, #0x0c, #0x08, #0x00 19 | .db #0x00, #0x04, #0x0e, #0x04, #0x0e, #0x04, #0x00, #0x00 20 | .db #0x00, #0x0a, #0x0a, #0x0a, #0x0a, #0x00, #0x0a, #0x00 21 | .db #0x00, #0x0e, #0x0b, #0x0b, #0x0a, #0x0a, #0x00, #0x00 22 | .db #0x06, #0x09, #0x06, #0x0f, #0x0e, #0x09, #0x06, #0x00 23 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x1f, #0x1f, #0x00 24 | .db #0x04, #0x0e, #0x04, #0x04, #0x0e, #0x04, #0x0e, #0x00 25 | .db #0x04, #0x0e, #0x04, #0x04, #0x04, #0x04, #0x00, #0x00 26 | .db #0x04, #0x04, #0x04, #0x04, #0x0e, #0x04, #0x00, #0x00 27 | .db #0x00, #0x00, #0x04, #0x0f, #0x04, #0x00, #0x00, #0x00 28 | .db #0x00, #0x00, #0x02, #0x0f, #0x02, #0x00, #0x00, #0x00 29 | .db #0x00, #0x00, #0x01, #0x01, #0x1f, #0x00, #0x00, #0x00 30 | .db #0x00, #0x00, #0x0a, #0x1f, #0x0a, #0x00, #0x00, #0x00 31 | .db #0x00, #0x00, #0x04, #0x0e, #0x1f, #0x00, #0x00, #0x00 32 | .db #0x00, #0x00, #0x1f, #0x0e, #0x04, #0x00, #0x00, #0x00 33 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 ; 032 - 34 | .db #0x04, #0x04, #0x04, #0x04, #0x04, #0x00, #0x04, #0x00 ; 033 - ! 35 | .db #0x0a, #0x0a, #0x0a, #0x00, #0x00, #0x00, #0x00, #0x00 ; 034 - " 36 | .db #0x00, #0x0a, #0x1f, #0x0a, #0x0a, #0x1f, #0x0a, #0x00 ; 035 - # 37 | .db #0x04, #0x0e, #0x05, #0x06, #0x0c, #0x0c, #0x07, #0x04 ; 036 - $ 38 | .db #0x08, #0x09, #0x05, #0x04, #0x02, #0x0a, #0x09, #0x01 ; 037 - % 39 | .db #0x04, #0x0a, #0x0a, #0x06, #0x05, #0x09, #0x16, #0x00 ; 038 - & 40 | .db #0x04, #0x04, #0x04, #0x00, #0x00, #0x00, #0x00, #0x00 ; 039 - ' 41 | .db #0x08, #0x04, #0x02, #0x02, #0x02, #0x02, #0x04, #0x08 ; 040 - ( 42 | .db #0x02, #0x04, #0x08, #0x08, #0x08, #0x08, #0x04, #0x02 ; 041 - ) 43 | .db #0x00, #0x00, #0x09, #0x06, #0x0f, #0x06, #0x09, #0x00 ; 042 - * 44 | .db #0x00, #0x00, #0x04, #0x04, #0x1f, #0x04, #0x04, #0x00 ; 043 - + 45 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x04, #0x04, #0x02 ; 044 - , 46 | .db #0x00, #0x00, #0x00, #0x00, #0x0f, #0x00, #0x00, #0x00 ; 045 - - 47 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x04, #0x00 ; 046 - . 48 | .db #0x08, #0x08, #0x04, #0x04, #0x02, #0x02, #0x01, #0x01 ; 047 - / 49 | .db #0x00, #0x06, #0x09, #0x0d, #0x0b, #0x09, #0x06, #0x00 ; 048 - 0 50 | .db #0x00, #0x04, #0x06, #0x04, #0x04, #0x04, #0x0e, #0x00 ; 049 - 1 51 | .db #0x00, #0x06, #0x09, #0x08, #0x06, #0x01, #0x0f, #0x00 ; 050 - 2 52 | .db #0x00, #0x06, #0x09, #0x04, #0x08, #0x09, #0x06, #0x00 ; 051 - 3 53 | .db #0x00, #0x01, #0x05, #0x05, #0x0f, #0x04, #0x04, #0x00 ; 052 - 4 54 | .db #0x00, #0x0f, #0x01, #0x0f, #0x08, #0x08, #0x07, #0x00 ; 053 - 5 55 | .db #0x00, #0x06, #0x01, #0x07, #0x09, #0x09, #0x06, #0x00 ; 054 - 6 56 | .db #0x00, #0x0f, #0x09, #0x04, #0x04, #0x02, #0x02, #0x00 ; 055 - 7 57 | .db #0x00, #0x06, #0x09, #0x06, #0x09, #0x09, #0x06, #0x00 ; 056 - 8 58 | .db #0x00, #0x06, #0x09, #0x09, #0x0e, #0x08, #0x06, #0x00 ; 057 - 9 59 | .db #0x00, #0x00, #0x00, #0x04, #0x00, #0x00, #0x04, #0x00 ; 058 - : 60 | .db #0x00, #0x00, #0x00, #0x04, #0x00, #0x04, #0x04, #0x02 ; 059 - ; 61 | .db #0x00, #0x08, #0x04, #0x02, #0x02, #0x04, #0x08, #0x00 ; 060 - < 62 | .db #0x00, #0x00, #0x00, #0x0f, #0x00, #0x0f, #0x00, #0x00 ; 061 - = 63 | .db #0x00, #0x02, #0x04, #0x08, #0x08, #0x04, #0x02, #0x00 ; 062 - > 64 | .db #0x06, #0x09, #0x08, #0x04, #0x02, #0x00, #0x02, #0x00 ; 063 - ? 65 | .db #0x00, #0x06, #0x09, #0x0d, #0x0d, #0x01, #0x0e, #0x00 ; 064 - @ 66 | .db #0x00, #0x06, #0x09, #0x09, #0x0f, #0x09, #0x09, #0x00 ; 065 - A 67 | .db #0x00, #0x07, #0x09, #0x07, #0x09, #0x09, #0x07, #0x00 ; 066 - B 68 | .db #0x00, #0x0e, #0x01, #0x01, #0x01, #0x01, #0x0e, #0x00 ; 067 - C 69 | .db #0x00, #0x07, #0x09, #0x09, #0x09, #0x09, #0x07, #0x00 ; 068 - D 70 | .db #0x00, #0x0e, #0x01, #0x07, #0x01, #0x01, #0x0e, #0x00 ; 069 - E 71 | .db #0x00, #0x0e, #0x01, #0x01, #0x07, #0x01, #0x01, #0x00 ; 070 - F 72 | .db #0x00, #0x0e, #0x01, #0x0d, #0x09, #0x09, #0x0e, #0x00 ; 071 - G 73 | .db #0x00, #0x09, #0x09, #0x0f, #0x09, #0x09, #0x09, #0x00 ; 072 - H 74 | .db #0x00, #0x0e, #0x04, #0x04, #0x04, #0x04, #0x0e, #0x00 ; 073 - I 75 | .db #0x00, #0x0e, #0x04, #0x04, #0x04, #0x04, #0x03, #0x00 ; 074 - J 76 | .db #0x00, #0x09, #0x09, #0x07, #0x09, #0x09, #0x09, #0x00 ; 075 - K 77 | .db #0x00, #0x01, #0x01, #0x01, #0x01, #0x01, #0x0e, #0x00 ; 076 - L 78 | .db #0x00, #0x09, #0x0f, #0x0f, #0x09, #0x09, #0x09, #0x00 ; 077 - M 79 | .db #0x00, #0x09, #0x0b, #0x0b, #0x0d, #0x0d, #0x09, #0x00 ; 078 - N 80 | .db #0x00, #0x06, #0x09, #0x09, #0x09, #0x09, #0x06, #0x00 ; 079 - O 81 | .db #0x00, #0x07, #0x09, #0x09, #0x07, #0x01, #0x01, #0x00 ; 080 - P 82 | .db #0x00, #0x06, #0x09, #0x09, #0x09, #0x09, #0x06, #0x0c ; 081 - Q 83 | .db #0x00, #0x07, #0x09, #0x09, #0x07, #0x09, #0x09, #0x00 ; 082 - R 84 | .db #0x00, #0x0e, #0x01, #0x06, #0x08, #0x08, #0x07, #0x00 ; 083 - S 85 | .db #0x00, #0x1f, #0x04, #0x04, #0x04, #0x04, #0x04, #0x00 ; 084 - T 86 | .db #0x00, #0x09, #0x09, #0x09, #0x09, #0x09, #0x0e, #0x00 ; 085 - U 87 | .db #0x00, #0x09, #0x09, #0x09, #0x09, #0x06, #0x06, #0x00 ; 086 - V 88 | .db #0x00, #0x09, #0x09, #0x09, #0x0f, #0x0f, #0x09, #0x00 ; 087 - W 89 | .db #0x00, #0x09, #0x09, #0x06, #0x06, #0x09, #0x09, #0x00 ; 088 - X 90 | .db #0x00, #0x09, #0x09, #0x09, #0x0e, #0x08, #0x07, #0x00 ; 089 - Y 91 | .db #0x00, #0x0f, #0x08, #0x04, #0x02, #0x01, #0x0f, #0x00 ; 090 - Z 92 | .db #0x0e, #0x02, #0x02, #0x02, #0x02, #0x02, #0x02, #0x0e ; 091 - [ 93 | .db #0x01, #0x01, #0x02, #0x02, #0x04, #0x04, #0x08, #0x08 ; 092 - \ 94 | .db #0x0e, #0x08, #0x08, #0x08, #0x08, #0x08, #0x08, #0x0e ; 093 - ] 95 | .db #0x00, #0x04, #0x0a, #0x11, #0x00, #0x00, #0x00, #0x00 ; 094 - ^ 96 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x0f ; 095 - _ 97 | .db #0x02, #0x04, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 ; 096 - ` 98 | .db #0x00, #0x00, #0x06, #0x08, #0x0e, #0x09, #0x0e, #0x00 ; 097 - a 99 | .db #0x01, #0x01, #0x07, #0x09, #0x09, #0x09, #0x07, #0x00 ; 098 - b 100 | .db #0x00, #0x00, #0x0e, #0x01, #0x01, #0x01, #0x0e, #0x00 ; 099 - c 101 | .db #0x08, #0x08, #0x0e, #0x09, #0x09, #0x09, #0x0e, #0x00 ; 100 - d 102 | .db #0x00, #0x00, #0x0e, #0x09, #0x0f, #0x01, #0x0e, #0x00 ; 101 - e 103 | .db #0x0c, #0x02, #0x02, #0x07, #0x02, #0x02, #0x02, #0x00 ; 102 - f 104 | .db #0x00, #0x00, #0x0e, #0x09, #0x09, #0x06, #0x08, #0x07 ; 103 - g 105 | .db #0x01, #0x01, #0x07, #0x09, #0x09, #0x09, #0x09, #0x00 ; 104 - h 106 | .db #0x00, #0x04, #0x00, #0x04, #0x04, #0x04, #0x04, #0x00 ; 105 - i 107 | .db #0x00, #0x04, #0x00, #0x04, #0x04, #0x04, #0x04, #0x03 ; 106 - j 108 | .db #0x01, #0x01, #0x09, #0x05, #0x03, #0x05, #0x09, #0x00 ; 107 - k 109 | .db #0x02, #0x02, #0x02, #0x02, #0x02, #0x02, #0x0c, #0x00 ; 108 - l 110 | .db #0x00, #0x00, #0x09, #0x0f, #0x0f, #0x09, #0x09, #0x00 ; 109 - m 111 | .db #0x00, #0x00, #0x07, #0x09, #0x09, #0x09, #0x09, #0x00 ; 110 - n 112 | .db #0x00, #0x00, #0x06, #0x09, #0x09, #0x09, #0x06, #0x00 ; 111 - o 113 | .db #0x00, #0x00, #0x07, #0x09, #0x09, #0x07, #0x01, #0x01 ; 112 - p 114 | .db #0x00, #0x00, #0x0e, #0x09, #0x09, #0x0e, #0x08, #0x08 ; 113 - q 115 | .db #0x00, #0x00, #0x0e, #0x09, #0x01, #0x01, #0x01, #0x00 ; 114 - r 116 | .db #0x00, #0x00, #0x0e, #0x01, #0x06, #0x08, #0x07, #0x00 ; 115 - s 117 | .db #0x02, #0x02, #0x07, #0x02, #0x02, #0x02, #0x0c, #0x00 ; 116 - t 118 | .db #0x00, #0x00, #0x09, #0x09, #0x09, #0x09, #0x0e, #0x00 ; 117 - u 119 | .db #0x00, #0x00, #0x09, #0x09, #0x09, #0x06, #0x06, #0x00 ; 118 - v 120 | .db #0x00, #0x00, #0x09, #0x09, #0x0f, #0x0f, #0x09, #0x00 ; 119 - w 121 | .db #0x00, #0x00, #0x09, #0x06, #0x06, #0x09, #0x09, #0x00 ; 120 - x 122 | .db #0x00, #0x00, #0x09, #0x09, #0x09, #0x0e, #0x08, #0x07 ; 121 - y 123 | .db #0x00, #0x00, #0x0f, #0x08, #0x04, #0x02, #0x0f, #0x00 ; 122 - z 124 | .db #0x0c, #0x02, #0x02, #0x03, #0x03, #0x02, #0x02, #0x0c ; 123 - { 125 | .db #0x00, #0x04, #0x04, #0x04, #0x04, #0x04, #0x04, #0x00 ; 124 - | 126 | .db #0x03, #0x04, #0x04, #0x0c, #0x0c, #0x04, #0x04, #0x03 ; 125 - } 127 | .db #0x00, #0x12, #0x0d, #0x00, #0x00, #0x00, #0x00, #0x00 ; 126 - ~ 128 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 129 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 130 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 131 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 132 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 133 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 134 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 135 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 136 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 137 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 138 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 139 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 140 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 141 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 142 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 143 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 144 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 145 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 146 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 147 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 148 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 149 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 150 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 151 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 152 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 153 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 154 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 155 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 156 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 157 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 158 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 159 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 160 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 161 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 162 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 163 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 164 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 165 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 166 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 167 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 168 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 169 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 170 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 171 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 172 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 173 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 174 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 175 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 176 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 177 | .db #0x00, #0x15, #0x00, #0x15, #0x00, #0x15, #0x00, #0x15 178 | .db #0x0a, #0x15, #0x0a, #0x15, #0x0a, #0x15, #0x0a, #0x15 179 | .db #0x1f, #0x0a, #0x1f, #0x0a, #0x1f, #0x0a, #0x1f, #0x0a 180 | .db #0x04, #0x04, #0x04, #0x04, #0x04, #0x04, #0x04, #0x04 181 | .db #0x04, #0x04, #0x04, #0x04, #0x07, #0x04, #0x04, #0x04 182 | .db #0x04, #0x04, #0x04, #0x07, #0x04, #0x07, #0x04, #0x04 183 | .db #0x0a, #0x0a, #0x0a, #0x0a, #0x0b, #0x0a, #0x0a, #0x0a 184 | .db #0x00, #0x00, #0x00, #0x00, #0x0f, #0x0a, #0x0a, #0x0a 185 | .db #0x00, #0x00, #0x00, #0x07, #0x04, #0x07, #0x04, #0x04 186 | .db #0x0a, #0x0a, #0x0a, #0x0b, #0x08, #0x0b, #0x0a, #0x0a 187 | .db #0x0a, #0x0a, #0x0a, #0x0a, #0x0a, #0x0a, #0x0a, #0x0a 188 | .db #0x00, #0x00, #0x00, #0x0f, #0x08, #0x0b, #0x0a, #0x0a 189 | .db #0x0a, #0x0a, #0x0a, #0x0b, #0x08, #0x0f, #0x00, #0x00 190 | .db #0x0a, #0x0a, #0x0a, #0x0a, #0x0f, #0x00, #0x00, #0x00 191 | .db #0x04, #0x04, #0x04, #0x07, #0x04, #0x07, #0x00, #0x00 192 | .db #0x00, #0x00, #0x00, #0x00, #0x07, #0x04, #0x04, #0x04 193 | .db #0x04, #0x04, #0x04, #0x04, #0x3c, #0x00, #0x00, #0x00 194 | .db #0x04, #0x04, #0x04, #0x04, #0x3f, #0x00, #0x00, #0x00 195 | .db #0x00, #0x00, #0x00, #0x00, #0x3f, #0x04, #0x04, #0x04 196 | .db #0x04, #0x04, #0x04, #0x04, #0x3c, #0x04, #0x04, #0x04 197 | .db #0x00, #0x00, #0x00, #0x00, #0x3f, #0x00, #0x00, #0x00 198 | .db #0x04, #0x04, #0x04, #0x04, #0x3f, #0x04, #0x04, #0x04 199 | .db #0x04, #0x04, #0x04, #0x3c, #0x04, #0x3c, #0x04, #0x04 200 | .db #0x0a, #0x0a, #0x0a, #0x0a, #0x3a, #0x0a, #0x0a, #0x0a 201 | .db #0x0a, #0x0a, #0x0a, #0x3a, #0x02, #0x3e, #0x00, #0x00 202 | .db #0x00, #0x00, #0x00, #0x3e, #0x02, #0x3a, #0x0a, #0x0a 203 | .db #0x0a, #0x0a, #0x0a, #0x3b, #0x00, #0x3f, #0x00, #0x00 204 | .db #0x00, #0x00, #0x00, #0x3f, #0x00, #0x3b, #0x0a, #0x0a 205 | .db #0x0a, #0x0a, #0x0a, #0x3a, #0x02, #0x3a, #0x0a, #0x0a 206 | .db #0x00, #0x00, #0x00, #0x3f, #0x00, #0x3f, #0x00, #0x00 207 | .db #0x0a, #0x0a, #0x0a, #0x3b, #0x00, #0x3b, #0x0a, #0x0a 208 | .db #0x04, #0x04, #0x04, #0x3f, #0x00, #0x3f, #0x00, #0x00 209 | .db #0x0a, #0x0a, #0x0a, #0x3f, #0x00, #0x3f, #0x00, #0x00 210 | .db #0x00, #0x00, #0x00, #0x3f, #0x00, #0x3f, #0x04, #0x04 211 | .db #0x00, #0x00, #0x00, #0x00, #0x3f, #0x0a, #0x0a, #0x0a 212 | .db #0x0a, #0x0a, #0x0a, #0x0a, #0x3f, #0x00, #0x00, #0x00 213 | .db #0x04, #0x04, #0x04, #0x3c, #0x04, #0x3c, #0x00, #0x00 214 | .db #0x00, #0x00, #0x00, #0x3c, #0x04, #0x3c, #0x04, #0x04 215 | .db #0x00, #0x00, #0x00, #0x00, #0x3e, #0x0a, #0x0a, #0x0a 216 | .db #0x0a, #0x0a, #0x0a, #0x0a, #0x3f, #0x0a, #0x0a, #0x0a 217 | .db #0x04, #0x04, #0x04, #0x3f, #0x00, #0x3f, #0x04, #0x04 218 | .db #0x04, #0x04, #0x04, #0x04, #0x07, #0x00, #0x00, #0x00 219 | .db #0x00, #0x00, #0x00, #0x00, #0x3c, #0x04, #0x04, #0x04 220 | .db #0x1f, #0x1f, #0x1f, #0x1f, #0x1f, #0x1f, #0x1f, #0x1f 221 | .db #0x00, #0x00, #0x00, #0x1f, #0x1f, #0x1f, #0x1f, #0x1f 222 | .db #0x07, #0x07, #0x07, #0x07, #0x07, #0x07, #0x07, #0x07 223 | .db #0x1c, #0x1c, #0x1c, #0x1c, #0x1c, #0x1c, #0x1c, #0x1c 224 | .db #0x1f, #0x1f, #0x1f, #0x1f, #0x00, #0x00, #0x00, #0x00 225 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 226 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 227 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 228 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 229 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 230 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 231 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 232 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 233 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 234 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 235 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 236 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 237 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 238 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 239 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 240 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 241 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 242 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 243 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 244 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 245 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 246 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 247 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 248 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 249 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 250 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 251 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 252 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 253 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 254 | .db #0x0e, #0x08, #0x04, #0x0e, #0x00, #0x00, #0x00, #0x00 255 | .db #0x00, #0x00, #0x0f, #0x0f, #0x0f, #0x0f, #0x00, #0x00 256 | .db #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00, #0x00 257 | -------------------------------------------------------------------------------- /lib/getchar.s: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8 2 | ; 3 | ; MailStation example program 4 | ; Copyright (c) 2019-2021 joshua stein 5 | ; 6 | ; Permission to use, copy, modify, and distribute this software for any 7 | ; purpose with or without fee is hereby granted, provided that the above 8 | ; copyright notice and this permission notice appear in all copies. 9 | ; 10 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | ; 18 | 19 | .module getchar 20 | 21 | .include "mailstation.inc" 22 | 23 | .area _DATA 24 | 25 | ; scancode_table holds three tables of ascii characters which 26 | ; '_getchar' uses to determine which character to return, depending on 27 | ; the scancode pressed and the state of the shift and caps lock keys. 28 | .include "scancodes.inc" 29 | 30 | keyboardbuffer: 31 | .ds 2 ; scancode buffer for _getchar 32 | capslock: 33 | .db #0 34 | 35 | .area _CODE 36 | 37 | ; unsigned char peekkey(void) 38 | ; check for a scancode using the firmware, then look it up in the scancode 39 | ; table (respecting the shift key and caps lock as control) and return the 40 | ; ascii value of the key in the l register 41 | _peekkey:: 42 | ld de, #keyboardbuffer 43 | push de 44 | call get_keycode_from_buffer 45 | pop de 46 | ld a, (keyboardbuffer) ; check for caps lock first 47 | cp #0x60 48 | jr z, is_caps_lock 49 | jr not_caps_lock 50 | is_caps_lock: 51 | ld a, (keyboardbuffer + 1) ; check flags 52 | bit 0, a ; set=pressed, reset=released 53 | jp nz, caps_down 54 | ld a, #0 ; caps lock released 55 | ld (capslock), a 56 | jr nokey 57 | caps_down: 58 | ld a, #1 59 | ld (capslock), a 60 | jr nokey 61 | not_caps_lock: 62 | ld a, (keyboardbuffer + 1) ; check flags 63 | bit 0, a ; set=pressed, reset=released 64 | jp z, nokey ; key was released, bail 65 | bit 6, a ; when set, shift was held down 66 | jr z, lowercase 67 | capital: 68 | ld hl, #scancode_table_uppercase 69 | jr char_offset 70 | lowercase: 71 | ld a, (capslock) 72 | cp #1 73 | jr z, as_control 74 | ld hl, #scancode_table 75 | jr char_offset 76 | as_control: 77 | ld hl, #scancode_table_control 78 | jr char_offset 79 | char_offset: 80 | push hl 81 | ld hl, #50 82 | push hl 83 | call _delay 84 | pop hl 85 | pop hl 86 | ld a, (keyboardbuffer) 87 | ld b, #0 88 | ld c, a 89 | add hl, bc 90 | ld a, (hl) 91 | ld h, #0 92 | ld l, a 93 | ret 94 | nokey: 95 | ld h, #0 96 | ld l, #0 97 | ret 98 | 99 | 100 | ; unsigned char getkey(void) 101 | ; peekkey() but loops until a key is available 102 | _getkey:: 103 | call _peekkey 104 | ld a, l 105 | cp #0 106 | jp z, _getkey 107 | ret 108 | 109 | 110 | ; int getchar(void) 111 | ; uses _getkey and filters out non-printables, returns in l register 112 | _getchar:: 113 | call _getkey 114 | ld a, l 115 | cp a, #META_KEY_BEGIN 116 | jr nc, _getchar ; a >= 117 | ret 118 | -------------------------------------------------------------------------------- /lib/mailstation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MailStation example program 3 | * Copyright (c) 2019-2021 joshua stein 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #ifndef _INCL_MAILSTATION 19 | #define _INCL_MAILSTATION 20 | 21 | #include "meta_keys.h" 22 | 23 | /* define some ports - see 0x1b2b */ 24 | __sfr __at(0x01) portkeyboard; 25 | __sfr __at(0x02) port2; 26 | __sfr __at(0x05) slot4000page; 27 | __sfr __at(0x06) slot4000device; 28 | __sfr __at(0x07) slot8000page; 29 | __sfr __at(0x08) slot8000device; 30 | __sfr __at(0x09) portpowerstatus; 31 | __sfr __at(0x0d) portcpuclockrate; 32 | __sfr __at(0x10) rtcseconds; 33 | __sfr __at(0x11) rtc10seconds; 34 | __sfr __at(0x12) rtcminutes; 35 | __sfr __at(0x13) rtc10minutes; 36 | __sfr __at(0x14) rtchours; 37 | __sfr __at(0x15) rtc10hours; 38 | __sfr __at(0x16) rtcdayofweek; 39 | __sfr __at(0x17) rtcdays; 40 | __sfr __at(0x18) rtc10days; 41 | __sfr __at(0x19) rtcmonths; 42 | __sfr __at(0x1a) rtc10months; 43 | __sfr __at(0x1b) rtcyears; 44 | __sfr __at(0x1c) rtc10years; 45 | __sfr __at(0x28) port28; 46 | 47 | /* defined according to whether we're running from RAM or flash */ 48 | #ifdef LOC_RAM 49 | #define RUN_ADDR 0x8000 50 | #define RUN_DEVICE 0x8 51 | #define RUN_PAGE 0x7 52 | #define SLOT_ADDR 0x4000 53 | #define SLOT_DEVICE 0x6 54 | #define SLOT_PAGE 0x5 55 | #elif defined(LOC_FLASH) 56 | #define RUN_ADDR 0x4000 57 | #define RUN_DEVICE 0x6 58 | #define RUN_PAGE 0x5 59 | #define SLOT_ADDR 0x8000 60 | #define SLOT_DEVICE 0x8 61 | #define SLOT_PAGE 0x7 62 | #else 63 | #error "no LOC_RAM or LOC_FLASH defined" 64 | #endif 65 | 66 | /* devices to load into slot4000device or slot8000device */ 67 | #define DEVICE_RAM 0x01 68 | #define DEVICE_LCD_LEFT 0x02 69 | #define DEVICE_DATAFLASH 0x03 70 | #define DEVICE_LCD_RIGHT 0x04 71 | #define DEVICE_MODEM 0x05 72 | 73 | /* LCD parameters (2 screens) */ 74 | #define LCD_WIDTH (160 * 2) // 320 75 | #define LCD_HEIGHT 128 76 | #define LCD_COL_GROUPS 20 77 | #define LCD_COL_GROUP_WIDTH 8 78 | 79 | #define FONT_WIDTH 5 80 | #define FONT_HEIGHT 8 81 | 82 | /* columns of characters */ 83 | #define LCD_COLS (LCD_WIDTH / FONT_WIDTH) // 64 84 | #define LCD_ROWS (LCD_HEIGHT / FONT_HEIGHT) // 16 85 | #define TEXT_COLS LCD_COLS // 64 86 | #define TEXT_ROWS (LCD_ROWS - 1) // 15 87 | 88 | #define ATTR_CURSOR (1 << 0) 89 | #define ATTR_REVERSE (1 << 1) 90 | #define ATTR_BOLD (1 << 2) 91 | #define ATTR_UNDERLINE (1 << 3) 92 | 93 | /* for printf */ 94 | #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" 95 | #define BYTE_TO_BINARY(byte) \ 96 | (byte & 0x80 ? '1' : '0'), \ 97 | (byte & 0x40 ? '1' : '0'), \ 98 | (byte & 0x20 ? '1' : '0'), \ 99 | (byte & 0x10 ? '1' : '0'), \ 100 | (byte & 0x08 ? '1' : '0'), \ 101 | (byte & 0x04 ? '1' : '0'), \ 102 | (byte & 0x02 ? '1' : '0'), \ 103 | (byte & 0x01 ? '1' : '0') 104 | 105 | 106 | /* for debugging access from asm */ 107 | extern unsigned char debug0; 108 | extern unsigned char debug1; 109 | extern unsigned char debug2; 110 | extern unsigned char debug3; 111 | extern unsigned char debug4; 112 | 113 | 114 | /* crt0.s */ 115 | extern void exit(void); 116 | extern void powerdown(void); 117 | extern void new_mail(unsigned char on); 118 | extern void reboot(void); 119 | extern void delay(unsigned int millis); 120 | extern void blink(unsigned int millis); 121 | extern unsigned char read_port(unsigned char port); 122 | 123 | 124 | /* putchar.s */ 125 | extern unsigned char cursorx; 126 | extern unsigned char cursory; 127 | extern unsigned char putchar_sgr; 128 | extern unsigned char putchar_quick; 129 | extern unsigned char *font_addr; 130 | extern void screen_init(void); 131 | extern void lcd_cas(unsigned char col); 132 | extern void lcd_sleep(void); 133 | extern void lcd_wake(void); 134 | extern void uncursor(void); 135 | extern void recursor(void); 136 | extern void clear_screen(void); 137 | extern void clear_screen_bufs(void); 138 | extern void redraw_screen(void); 139 | extern void scroll_lcd_half(void); 140 | extern void clear_lcd_half(void); 141 | extern void stamp_char(unsigned char row, unsigned char col); 142 | extern void putchar_attr(unsigned char row, unsigned char col, unsigned char c, 143 | unsigned char attr); 144 | 145 | 146 | /* getchar.s */ 147 | extern unsigned char getscancode(unsigned char *charbuffer); 148 | extern int getkey(void); 149 | extern int peekkey(void); 150 | 151 | 152 | /* wifi.s */ 153 | void wifi_init(void); 154 | extern int wifi_write(char); 155 | extern int wifi_read(void); 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /lib/mailstation.inc: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8:sw=8 2 | ; 3 | ; MailStation example program 4 | ; Copyright (c) 2019-2021 joshua stein 5 | ; 6 | ; Permission to use, copy, modify, and distribute this software for any 7 | ; purpose with or without fee is hereby granted, provided that the above 8 | ; copyright notice and this permission notice appear in all copies. 9 | ; 10 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | ; 18 | 19 | ; these are defined in addrs-*, either of which is linked into the 20 | ; build based on where we're running from 21 | .globl RUN_ADDR 22 | .globl RUN_DEVICE 23 | .globl RUN_PAGE 24 | .globl SLOT_ADDR 25 | .globl SLOT_DEVICE 26 | .globl SLOT_PAGE 27 | 28 | ; per-firmware version port shadow variables 29 | .globl p2shadow 30 | .globl p3shadow 31 | .globl p28shadow 32 | 33 | ; functions 34 | .equ get_keycode_from_buffer,#0x0a9a 35 | .equ lcd_buf_to_screen, #0x2473 36 | 37 | ; lcd bit storage buffer, copied with lcd_buf_to_screen 38 | .equ lcd_buf, #0xc010 39 | .equ lcd_buf_end, #lcd_buf + ((LCD_WIDTH * LCD_HEIGHT) / 8) - 1 40 | 41 | .equ LCD_WIDTH, #160 * 2 ; 320 42 | .equ LCD_HEIGHT, #128 43 | .equ LCD_COL_GROUPS, #20 44 | .equ LCD_COL_GROUP_WIDTH, #8 45 | .equ FONT_WIDTH, #5 46 | .equ FONT_HEIGHT, #8 47 | .equ LCD_COLS, #LCD_WIDTH / FONT_WIDTH ; 64 48 | .equ LCD_ROWS, #LCD_HEIGHT / FONT_HEIGHT ; 16 49 | .equ TEXT_ROWS, #LCD_ROWS - 1 ; 15 50 | 51 | .equ DEVICE_RAM, #0x01 52 | .equ DEVICE_LCD_LEFT, #0x02 53 | .equ DEVICE_DATAFLASH, #0x03 54 | .equ DEVICE_LCD_RIGHT, #0x04 55 | .equ DEVICE_MODEM, #0x05 56 | 57 | ; addressing the LCD once it's loaded in SLOT_ADDR 58 | .equ LCD_START, #SLOT_ADDR + 0x0038 59 | 60 | .equ ATTR_BIT_CURSOR, #0 61 | .equ ATTR_BIT_REVERSE, #1 62 | .equ ATTR_BIT_BOLD, #2 63 | .equ ATTR_BIT_UNDERLINE, #3 64 | 65 | .equ ATTR_CURSOR, #(1 << ATTR_CURSOR) 66 | .equ ATTR_REVERSE, #(1 << ATTR_REVERSE) 67 | .equ ATTR_BOLD, #(1 << ATTR_BOLD) 68 | .equ ATTR_UNDERLINE, #(1 << ATTR_UNDERLINE) 69 | 70 | .globl _saved_cursorx 71 | .globl _saved_cursory 72 | .globl _delay 73 | 74 | ; debug variables 75 | .globl _debug0 76 | .globl _debug1 77 | .globl _debug2 78 | .globl _debug3 79 | .globl _debug4 80 | -------------------------------------------------------------------------------- /lib/meta_keys.h: -------------------------------------------------------------------------------- 1 | /* AUTOMATICALLY GENERATED FILE - see tools/generate_scancodes.rb */ 2 | #define META_KEY_BEGIN 200 3 | #define KEY_MAIN_MENU 200 4 | #define KEY_BACK 201 5 | #define KEY_PRINT 202 6 | #define KEY_F1 203 7 | #define KEY_F2 204 8 | #define KEY_F3 205 9 | #define KEY_F4 206 10 | #define KEY_F5 207 11 | #define KEY_POWER 208 12 | #define KEY_SIZE 209 13 | #define KEY_SPELLING 210 14 | #define KEY_EMAIL 211 15 | #define KEY_PAGE_UP 212 16 | #define KEY_PAGE_DOWN 213 17 | #define KEY_CAPS_LOCK 214 18 | #define KEY_LEFT_SHIFT 215 19 | #define KEY_RIGHT_SHIFT 216 20 | #define KEY_FN 217 21 | #define KEY_UP 218 22 | #define KEY_DOWN 219 23 | #define KEY_LEFT 220 24 | #define KEY_RIGHT 221 25 | 26 | #define META_KEY_NONE 255 27 | -------------------------------------------------------------------------------- /lib/putchar.s: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8 2 | ; 3 | ; putchar for 5x8 font 4 | ; Copyright (c) 2019-2021 joshua stein 5 | ; 6 | ; Permission to use, copy, modify, and distribute this software for any 7 | ; purpose with or without fee is hereby granted, provided that the above 8 | ; copyright notice and this permission notice appear in all copies. 9 | ; 10 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | ; 18 | 19 | .module putchar 20 | 21 | .include "mailstation.inc" 22 | 23 | ; screen contents (characters) array in upper memory 24 | .equ _screenbuf, #0xc000 25 | .equ _screenbufend, #0xc3ff 26 | 27 | ; per-character attributes array in upper memory 28 | .equ _screenattrs, #0xc400 29 | .equ _screenattrsend, #0xc7ff 30 | 31 | .area _DATA 32 | 33 | font_data:: 34 | .include "font/spleen-5x8.inc" 35 | 36 | ; lookup table for putchar 37 | ; left-most 5 bits are col group for lcd_cas 38 | ; last 3 bits are offset into col group 39 | cursorx_lookup_data:: 40 | .include "cursorx_lookup.inc" 41 | 42 | _cursorx:: ; cursor x position, 0-indexed 43 | .db #0 44 | _cursory:: ; cursor y position, 0-indexed 45 | .db #0 46 | _saved_cursorx:: ; cursor x position, 0-indexed 47 | .db #0 48 | _saved_cursory:: ; cursor y position, 0-indexed 49 | .db #0 50 | _putchar_sgr:: ; current SGR for putchar() 51 | .db #0 52 | 53 | 54 | .area _CODE 55 | 56 | ; void screen_init(void) 57 | ; quick initialization of the screen 58 | _screen_init:: 59 | push hl 60 | call _clear_screen_bufs 61 | call _clear_screen 62 | call _recursor 63 | ld hl, #0 64 | push hl 65 | push hl 66 | call _stamp_char 67 | pop hl 68 | pop hl 69 | pop hl 70 | ret 71 | 72 | 73 | ; void lcd_cas(unsigned char col) 74 | ; enable CAS, address the LCD column col (in h), and disable CAS 75 | _lcd_cas:: 76 | push ix 77 | ld ix, #0 78 | add ix, sp 79 | push de 80 | push hl 81 | ld hl, (p2shadow) 82 | ld a, (hl) 83 | and #0b11110111 ; CAS(0) - turn port2 bit 3 off 84 | ld (hl), a 85 | out (#0x02), a ; write p2shadow to port2 86 | ld de, #LCD_START 87 | ld a, 4(ix) 88 | ld (de), a ; write col argument 89 | ld a, (hl) 90 | or #0b00001000 ; CAS(1) - turn port2 bit 3 on 91 | ld (hl), a 92 | out (#0x02), a 93 | pop hl 94 | pop de 95 | ld sp, ix 96 | pop ix 97 | ret 98 | 99 | 100 | ; void clear_screen(void) 101 | _clear_screen:: 102 | di 103 | push hl 104 | in a, (#SLOT_DEVICE) 105 | ld h, a 106 | in a, (#SLOT_PAGE) 107 | ld l, a 108 | push hl 109 | ld a, #DEVICE_LCD_RIGHT 110 | out (#SLOT_DEVICE), a 111 | call _clear_lcd_half 112 | ld a, #DEVICE_LCD_LEFT 113 | out (#SLOT_DEVICE), a 114 | call _clear_lcd_half 115 | pop hl 116 | ld a, h 117 | out (#SLOT_DEVICE), a 118 | ld a, l 119 | out (#SLOT_PAGE), a 120 | pop hl 121 | ei 122 | ret 123 | 124 | _clear_screen_bufs:: 125 | di 126 | push bc 127 | push de 128 | push hl 129 | xor a 130 | ld (_cursorx), a 131 | ld (_cursory), a 132 | ld (_saved_cursorx), a 133 | ld (_saved_cursory), a 134 | ld (_putchar_sgr), a 135 | zero_screenbuf: 136 | ld hl, #_screenbuf 137 | ld de, #_screenbuf + 1 138 | ld bc, #_screenbufend - _screenbuf 139 | ld (hl), #' ' 140 | ldir 141 | zero_screenattrs: 142 | ld hl, #_screenattrs 143 | ld de, #_screenattrs + 1 144 | ld bc, #_screenattrsend - _screenattrs 145 | ld (hl), #0 146 | ldir 147 | clear_screen_out: 148 | pop hl 149 | pop de 150 | pop bc 151 | ei 152 | ret 153 | 154 | 155 | ; void clear_lcd_half(void) 156 | ; zero out the current LCD module (must already be in SLOT_DEVICE) 157 | ; from v2.54 firmware at 0x2490 158 | _clear_lcd_half:: 159 | push bc 160 | push de 161 | ld b, #20 ; do 20 columns total 162 | clear_lcd_column: 163 | ld h, #0 164 | ld a, b 165 | dec a ; columns are 0-based 166 | ld l, a 167 | push hl 168 | call _lcd_cas 169 | pop hl 170 | push bc ; preserve our column counter 171 | ld hl, #LCD_START 172 | ld (hl), #0 ; zero out hl, then copy it to de 173 | ld de, #LCD_START + 1 ; de will always be the next line 174 | ld bc, #128 - 1 ; iterate (LCD_HEIGHT - 1) times 175 | ldir ; ld (de), (hl), bc-- until 0 176 | pop bc ; restore column counter 177 | djnz clear_lcd_column ; column--, if not zero keep going 178 | clear_done: 179 | pop de 180 | pop bc 181 | ret 182 | 183 | 184 | ; void redraw_screen(void) 185 | _redraw_screen:: 186 | push bc 187 | push de 188 | push hl 189 | ld b, #0 190 | redraw_rows: 191 | ld d, b ; store rows in d 192 | ld b, #0 193 | redraw_cols: 194 | push bc ; XXX figure out what is corrupting 195 | push de ; bc and de in stamp_char, these shouldn't be needed 196 | push hl 197 | ld h, #0 ; cols 198 | ld l, b 199 | push hl 200 | ld h, #0 ; rows 201 | ld l, d 202 | push hl 203 | call _stamp_char 204 | pop hl 205 | pop hl 206 | pop hl 207 | pop de 208 | pop bc 209 | redraw_cols_next: 210 | inc hl 211 | inc b 212 | ld a, b 213 | cp #LCD_COLS 214 | jr nz, redraw_cols 215 | ld b, d 216 | inc b 217 | ld a, b 218 | cp #LCD_ROWS 219 | jr nz, redraw_rows 220 | redraw_screen_out: 221 | pop hl 222 | pop de 223 | pop bc 224 | ret 225 | 226 | 227 | ; void scroll_lcd(void) 228 | ; scroll entire screen up by FONT_HEIGHT rows, minus statusbar 229 | _scroll_lcd:: 230 | di 231 | push bc 232 | push de 233 | push hl 234 | in a, (#SLOT_DEVICE) 235 | ld h, a 236 | in a, (#SLOT_PAGE) 237 | ld l, a 238 | push hl 239 | ld a, #DEVICE_LCD_LEFT 240 | out (#SLOT_DEVICE), a 241 | call _scroll_lcd_half 242 | ld a, #DEVICE_LCD_RIGHT 243 | out (#SLOT_DEVICE), a 244 | call _scroll_lcd_half 245 | pop hl 246 | ld a, h 247 | out (#SLOT_DEVICE), a 248 | ld a, l 249 | out (#SLOT_PAGE), a 250 | shift_bufs: 251 | ld b, #0 252 | screenbuf_shift_loop: 253 | ld h, b 254 | ld l, #0 255 | call screenbuf_offset 256 | ld de, #_screenbuf 257 | add hl, de ; hl = screenbuf[b * LCD_COLS] 258 | push hl 259 | ld de, #LCD_COLS 260 | add hl, de ; hl += LCD_COLS 261 | pop de ; de = screenbuf[b * LCD_COLS] 262 | push bc 263 | ld bc, #LCD_COLS 264 | ldir ; ld (de), (hl), de++, hl++, bc-- 265 | pop bc 266 | inc b 267 | ld a, b 268 | cp #TEXT_ROWS - 1 269 | jr nz, screenbuf_shift_loop 270 | screenattrs_shift: 271 | ld b, #0 272 | screenattrs_shift_loop: 273 | ld h, b 274 | ld l, #0 275 | call screenbuf_offset 276 | ld de, #_screenattrs 277 | add hl, de ; hl = screenattrs[b * LCD_COLS] 278 | push hl 279 | ld de, #LCD_COLS 280 | add hl, de 281 | pop de 282 | push bc 283 | ld bc, #LCD_COLS 284 | ldir 285 | pop bc 286 | inc b 287 | ld a, b 288 | cp #TEXT_ROWS - 1 289 | jr nz, screenattrs_shift_loop 290 | last_row_zero: 291 | ld a, #TEXT_ROWS - 1 292 | ld h, a 293 | ld l, #0 294 | call screenbuf_offset 295 | ld de, #_screenbuf 296 | add hl, de 297 | ld d, #0 298 | ld e, #LCD_COLS - 1 299 | add hl, de 300 | ld b, #LCD_COLS 301 | ld a, (_putchar_sgr) 302 | last_row_zero_loop: 303 | ld (hl), #' ' 304 | dec hl 305 | djnz last_row_zero_loop 306 | scroll_lcd_out: 307 | pop hl 308 | pop de 309 | pop bc 310 | ei 311 | ret 312 | 313 | 314 | ; void scroll_lcd_half(void) 315 | ; scroll current LCD module up by FONT_HEIGHT rows, minus statusbar and 316 | ; zero out the last line of text (only to the LCD) 317 | _scroll_lcd_half:: 318 | push ix 319 | ld ix, #0 320 | add ix, sp 321 | push bc 322 | push de 323 | push hl 324 | ; alloc 2 bytes on the stack for local storage 325 | push hl 326 | ld a, #LCD_HEIGHT - (FONT_HEIGHT * 2) ; iterations of pixel row moves 327 | scroll_init: 328 | ld -1(ix), a ; store iterations 329 | ld b, #20 ; do 20 columns total 330 | scroll_lcd_column: 331 | ld -2(ix), b ; store new column counter 332 | ld a, b 333 | sub #1 ; columns are 0-based 334 | ld h, #0 335 | ld l, a 336 | push hl 337 | call _lcd_cas 338 | pop hl 339 | scroll_rows: 340 | ld b, #0 341 | ld c, -1(ix) ; bc = row counter 342 | ld hl, #LCD_START + 8 ; start of next line 343 | ld de, #LCD_START 344 | ldir ; ld (de), (hl), bc-- until 0 345 | scroll_zerolast: 346 | ld hl, #LCD_START 347 | ld d, #0 348 | ld e, -1(ix) 349 | add hl, de 350 | ld b, #FONT_HEIGHT 351 | scroll_zerolastloop: ; 8 times: zero hl, hl++ 352 | ld (hl), #0 353 | inc hl 354 | djnz scroll_zerolastloop 355 | ld b, -2(ix) 356 | djnz scroll_lcd_column ; column--, if not zero keep going 357 | pop hl 358 | pop de 359 | pop bc 360 | ld sp, ix 361 | pop ix 362 | ret 363 | 364 | 365 | ; address of screenbuf or screenattrs offset for a row/col in hl, returns in hl 366 | screenbuf_offset: 367 | push bc 368 | push de 369 | ; uses hl 370 | ex de, hl 371 | ld hl, #0 372 | ld a, d ; row 373 | cp #0 374 | jr z, multiply_srow_out ; only add rows if > 0 375 | ld bc, #LCD_COLS 376 | multiply_srow: 377 | add hl, bc 378 | dec a 379 | cp #0 380 | jr nz, multiply_srow 381 | multiply_srow_out: 382 | ld d, #0 ; col in e 383 | add hl, de ; hl = (row * LCD_COLS) + col 384 | pop de 385 | pop bc 386 | ret ; hl 387 | 388 | 389 | ; void stamp_char(unsigned int row, unsigned int col) 390 | ; row at 4(ix), col at 6(ix) 391 | _stamp_char:: 392 | push ix 393 | ld ix, #0 394 | add ix, sp 395 | push bc 396 | push de 397 | push hl 398 | ld hl, #-15 ; stack bytes for local storage 399 | add hl, sp 400 | ld sp, hl 401 | in a, (#SLOT_DEVICE) 402 | ld -3(ix), a ; stack[-3] = old slot device 403 | in a, (#SLOT_PAGE) 404 | ld -4(ix), a ; stack[-4] = old slot page 405 | find_char: 406 | ld h, 4(ix) 407 | ld l, 6(ix) 408 | call screenbuf_offset 409 | push hl 410 | ld de, #_screenbuf 411 | add hl, de ; hl = screenbuf[(row * LCD_COLS) + col] 412 | ld a, (hl) 413 | ld -5(ix), a ; stack[-5] = character to stamp 414 | pop hl 415 | ld de, #_screenattrs 416 | add hl, de ; hl = screenattrs[(row * LCD_COLS) + col] 417 | ld a, (hl) 418 | ld -6(ix), a ; stack[-6] = character attrs 419 | calc_font_data_base: 420 | ld h, #0 421 | ld l, -5(ix) ; char 422 | add hl, hl ; hl = char * FONT_HEIGHT (8) 423 | add hl, hl 424 | add hl, hl 425 | ld de, #font_data 426 | add hl, de 427 | ld -7(ix), l 428 | ld -8(ix), h ; stack[-8,-7] = char font data base addr 429 | calc_char_cell_base: 430 | ld h, #0 431 | ld l, 4(ix) ; row 432 | add hl, hl 433 | add hl, hl 434 | add hl, hl ; hl = row * FONT_HEIGHT (8) 435 | ld de, #LCD_START 436 | add hl, de ; hl = 4038 + (row * FONT_HEIGHT) 437 | ld -9(ix), l 438 | ld -10(ix), h ; stack[-10,-9] = lcd char cell base 439 | fetch_from_table: 440 | ld a, 6(ix) ; col 441 | ld hl, #cursorx_lookup_data 442 | ld b, #0 443 | ld c, a 444 | add hl, bc 445 | ld b, (hl) 446 | ld a, b 447 | pluck_col_group: 448 | and #0b11111000 ; upper 5 bits are col group 449 | srl a 450 | srl a 451 | srl a 452 | ld -11(ix), a ; stack[-11] = col group 453 | pluck_offset: 454 | ld a, b 455 | and #0b00000111 ; lower 3 bits are offset 456 | ld -12(ix), a ; stack[-12] = offset 457 | ld -15(ix), #0 ; stack[-15] = previous lcd col 458 | ld d, #FONT_HEIGHT ; for (row = FONT_HEIGHT; row >= 0; row--) 459 | next_char_row: 460 | ld a, d 461 | dec a 462 | ld h, -8(ix) ; char font data base 463 | ld l, -7(ix) 464 | ld b, #0 465 | ld c, a 466 | add hl, bc 467 | ld a, (hl) ; font_addr + (char * FONT_HEIGHT) + row 468 | ld b, -6(ix) 469 | bit #ATTR_BIT_REVERSE, b 470 | jr nz, reverse 471 | bit #ATTR_BIT_CURSOR, b 472 | jr nz, reverse 473 | jr not_reverse 474 | reverse: 475 | cpl ; flip em 476 | and #0b00011111 ; mask off bits not within FONT_WIDTH 477 | not_reverse: 478 | ld -13(ix), a ; stack[-13] = working font data 479 | ld a, -6(ix) 480 | bit #ATTR_BIT_UNDERLINE, a 481 | jr z, not_underline 482 | ld a, d 483 | cp #FONT_HEIGHT 484 | jr nz, not_underline 485 | underline: 486 | ld -13(ix), #0xff 487 | not_underline: 488 | ld a, 6(ix) ; col 489 | cp #LCD_COLS / 2 ; assume a char never spans both LCD sides 490 | jr nc, rightside 491 | leftside: 492 | ld a, #DEVICE_LCD_LEFT 493 | jr swap_lcd 494 | rightside: 495 | ld a, #DEVICE_LCD_RIGHT 496 | swap_lcd: 497 | out (#SLOT_DEVICE), a 498 | ld e, #FONT_WIDTH ; for (col = FONT_WIDTH; col > 0; col--) 499 | next_char_col: ; inner loop, each col of each row 500 | ld -14(ix), #0b00011111 ; font data mask that will get shifted 501 | determine_cas: 502 | ld c, #0 503 | ld b, -11(ix) ; col group 504 | ld a, -12(ix) ; bit offset 505 | add #FONT_WIDTH 506 | sub e ; if offset+(5-col) is >= 8, advance col 507 | cp #LCD_COL_GROUP_WIDTH 508 | jr c, skip_advance ; if a >= 8, advance (dec b) 509 | dec b 510 | ld c, -12(ix) ; bit offset 511 | ld a, #LCD_COL_GROUP_WIDTH 512 | sub c 513 | ld c, a ; c = number of right shifts 514 | skip_advance: 515 | do_lcd_cas: 516 | ld a, -15(ix) ; previous lcd cas 517 | cp b 518 | jr z, prep_right_shift 519 | ld h, #0 520 | ld l, b 521 | push hl 522 | call _lcd_cas 523 | pop hl 524 | ld -15(ix), b ; store lcd col for next round 525 | ; if this character doesn't fit entirely in one lcd column, we need to 526 | ; span two of them and on the left one, shift font data and masks right 527 | ; to remove right-most bits that will be on the next column 528 | prep_right_shift: 529 | ld a, c 530 | cp #0 531 | jr z, prep_left_shift 532 | ld b, c 533 | ld c, -14(ix) ; matching mask 00011111 534 | ld a, -13(ix) ; load font data like 00010101 535 | right_shift: 536 | srl a ; shift font data right #b times 537 | srl c ; and mask to match 538 | djnz right_shift ; -> 10101000 539 | ld -14(ix), c 540 | jr done_left_shift 541 | prep_left_shift: 542 | ld c, -14(ix) ; mask 543 | ld a, -12(ix) ; (bit offset) times, shift font data 544 | cp #0 545 | ld b, a 546 | ld a, -13(ix) ; read new font data 547 | jr z, done_left_shift 548 | left_shift: 549 | sla a 550 | sla c 551 | djnz left_shift 552 | done_left_shift: 553 | ld b, a 554 | ld a, c 555 | cpl 556 | ld -14(ix), a ; store inverted mask 557 | ld a, b 558 | read_lcd_data: 559 | ld h, -10(ix) 560 | ld l, -9(ix) 561 | ld b, a 562 | ld a, d 563 | dec a 564 | ld c, a 565 | ld a, b 566 | ld b, #0 567 | add hl, bc ; hl = 4038 + (row * FONT_HEIGHT) + row - 1 568 | ld b, a ; store new font data 569 | ld a, (hl) ; read existing cell data 570 | and -14(ix) ; mask off new char cell 571 | or b ; combine data into cell 572 | ld (hl), a 573 | dec e 574 | jp nz, next_char_col 575 | dec d 576 | jp nz, next_char_row 577 | stamp_char_out: 578 | ld a, -3(ix) ; restore old slot device 579 | out (#SLOT_DEVICE), a 580 | ld a, -4(ix) ; restore old slot page 581 | out (#SLOT_PAGE), a 582 | ld hl, #15 ; remove stack bytes 583 | add hl, sp 584 | ld sp, hl 585 | pop hl 586 | pop de 587 | pop bc 588 | ld sp, ix 589 | pop ix 590 | ret 591 | 592 | 593 | ; void uncursor(void) 594 | ; remove cursor attribute from old cursor position 595 | _uncursor:: 596 | push de 597 | push hl 598 | ld a, (_cursory) 599 | ld h, a 600 | ld a, (_cursorx) 601 | ld l, a 602 | call screenbuf_offset 603 | ld de, #_screenattrs 604 | add hl, de ; screenattrs[(cursory * TEXT_COLS) + cursorx] 605 | ld a, (hl) 606 | res #ATTR_BIT_CURSOR, a ; &= ~(ATTR_CURSOR) 607 | ld (hl), a 608 | ld a, (_cursorx) 609 | ld l, a 610 | push hl 611 | ld a, (_cursory) 612 | ld l, a 613 | push hl 614 | call _stamp_char 615 | pop hl 616 | pop hl 617 | pop hl 618 | pop de 619 | ret 620 | 621 | ; void recursor(void) 622 | ; force-set cursor attribute 623 | _recursor:: 624 | push de 625 | push hl 626 | ld a, (_cursory) 627 | ld h, a 628 | ld a, (_cursorx) 629 | ld l, a 630 | call screenbuf_offset 631 | ld de, #_screenattrs 632 | add hl, de ; screenattrs[(cursory * TEXT_COLS) + cursorx] 633 | ld a, (hl) 634 | set #ATTR_BIT_CURSOR, a 635 | ld (hl), a 636 | pop hl 637 | pop de 638 | ret 639 | 640 | 641 | ; int putchar(int c) 642 | _putchar:: 643 | push ix 644 | ld ix, #0 645 | add ix, sp ; char to print is at 4(ix) 646 | push de 647 | push hl 648 | call _uncursor 649 | ld a, 4(ix) 650 | cp #'\b' ; backspace 651 | jr nz, not_backspace 652 | backspace: 653 | ld a, (_cursorx) 654 | cp #0 655 | jr nz, cursorx_not_zero 656 | ld a, (_cursory) 657 | cp #0 658 | jp z, putchar_fastout ; cursorx/y at 0,0, nothing to do 659 | dec a 660 | ld (_cursory), a ; cursory-- 661 | ld a, #LCD_COLS - 2 662 | ld (_cursorx), a 663 | jp putchar_draw_cursor 664 | cursorx_not_zero: 665 | dec a 666 | ld (_cursorx), a ; cursorx--; 667 | jp putchar_draw_cursor 668 | not_backspace: 669 | cp #'\r' 670 | jr nz, not_cr 671 | xor a 672 | ld (_cursorx), a ; cursorx = 0 673 | jr not_crlf 674 | not_cr: 675 | cp #'\n' 676 | jr nz, not_crlf 677 | xor a 678 | ld (_cursorx), a ; cursorx = 0 679 | ld a, (_cursory) 680 | inc a 681 | ld (_cursory), a ; cursory++ 682 | not_crlf: 683 | ld a, (_cursorx) 684 | cp #LCD_COLS 685 | jr c, not_longer_text_cols ; cursorx < TEXT_COLS 686 | xor a 687 | ld (_cursorx), a ; cursorx = 0 688 | ld a, (_cursory) 689 | inc a 690 | ld (_cursory), a 691 | not_longer_text_cols: 692 | ld a, (_cursory) 693 | cp #TEXT_ROWS 694 | jr c, scroll_out 695 | scroll_up_screen: 696 | call _scroll_lcd 697 | xor a 698 | ld (_cursorx), a 699 | ld a, #TEXT_ROWS - 1 700 | ld (_cursory), a ; cursory = TEXT_ROWS - 1 701 | scroll_out: 702 | ld a, 4(ix) 703 | cp a, #'\r' 704 | jr z, cr_or_lf 705 | cp a, #'\n' 706 | jr z, cr_or_lf 707 | jr store_char_in_buf 708 | cr_or_lf: 709 | jp putchar_draw_cursor 710 | store_char_in_buf: 711 | ld a, (_cursory) 712 | ld h, a 713 | ld a, (_cursorx) 714 | ld l, a 715 | call screenbuf_offset 716 | push hl 717 | ld de, #_screenbuf 718 | add hl, de ; hl = screenbuf[(cursory * LCD_COLS) + cursorx] 719 | ld a, 4(ix) 720 | ld (hl), a ; store character 721 | pop hl 722 | ld de, #_screenattrs 723 | add hl, de ; hl = screenattrs[(cursory * LCD_COLS) + cursorx] 724 | ld a, (_putchar_sgr) 725 | ld (hl), a ; = putchar_sgr 726 | ld a, (_cursorx) 727 | ld l, a 728 | push hl 729 | ld a, (_cursory) 730 | ld l, a 731 | push hl 732 | call _stamp_char 733 | pop hl 734 | pop hl 735 | advance_cursorx: 736 | ld a, (_cursorx) 737 | inc a 738 | ld (_cursorx), a 739 | cp #LCD_COLS ; if (cursorx >= LCD_COLS) 740 | jr c, putchar_draw_cursor 741 | xor a 742 | ld (_cursorx), a 743 | ld a, (_cursory) 744 | inc a 745 | ld (_cursory), a 746 | check_cursory: 747 | cp #TEXT_ROWS ; and if (cursory >= TEXT_ROWS) 748 | jr c, putchar_draw_cursor 749 | call _scroll_lcd 750 | ld a, #TEXT_ROWS - 1 751 | ld (_cursory), a ; cursory = TEXT_ROWS - 1 752 | putchar_draw_cursor: 753 | ld a, (_cursory) 754 | ld h, a 755 | ld a, (_cursorx) 756 | ld l, a 757 | call screenbuf_offset 758 | ld de, #_screenattrs 759 | add hl, de ; hl = screenattrs[(cursory * LCD_COLS) + cursorx] 760 | ld a, (hl) ; read existing attrs 761 | set #ATTR_BIT_CURSOR, a 762 | ld (hl), a ; = putchar_sgr | ATTR_CURSOR 763 | ld a, (_cursorx) 764 | ld l, a 765 | push hl 766 | ld a, (_cursory) 767 | ld l, a 768 | push hl 769 | call _stamp_char 770 | pop hl 771 | pop hl 772 | putchar_fastout: 773 | pop hl 774 | pop de 775 | ld sp, ix 776 | pop ix 777 | ret 778 | 779 | 780 | ; void putchar_attr(unsigned char row, unsigned char col, char c, char attr) 781 | ; directly manipulates screenbuf/attrs without scrolling or length checks 782 | ; row at 4(ix), col at 5(ix), c at 6(ix), attr at 7(ix) 783 | _putchar_attr:: 784 | push ix 785 | ld ix, #0 786 | add ix, sp 787 | push de 788 | push hl 789 | store_char: 790 | ld h, 4(ix) 791 | ld l, 5(ix) 792 | call screenbuf_offset 793 | push hl 794 | ld de, #_screenbuf 795 | add hl, de ; screenbuf[(row * TEXT_COLS) + col] 796 | ld a, 6(ix) 797 | ld (hl), a 798 | store_attrs: 799 | pop hl 800 | ld de, #_screenattrs 801 | add hl, de ; screenattrs[(row * TEXT_COLS) + col] 802 | ld a, 7(ix) 803 | ld (hl), a 804 | ld l, 5(ix) 805 | push hl 806 | ld l, 4(ix) 807 | push hl 808 | call _stamp_char 809 | pop hl 810 | pop hl 811 | pop hl 812 | pop de 813 | ld sp, ix 814 | pop ix 815 | ret 816 | -------------------------------------------------------------------------------- /lib/scancodes.inc: -------------------------------------------------------------------------------- 1 | ; AUTOMATICALLY GENERATED FILE - see tools/generate_scancodes.rb 2 | .equ META_KEY_BEGIN, #0d200 3 | .equ META_KEY_NONE, #0d255 4 | 5 | scancode_table: 6 | .db #0d200 ; :MAIN_MENU 7 | .db #0d201 ; :BACK 8 | .db #0d202 ; :PRINT 9 | .db #0d203 ; :F1 10 | .db #0d204 ; :F2 11 | .db #0d205 ; :F3 12 | .db #0d206 ; :F4 13 | .db #0d207 ; :F5 14 | .db #0d255 15 | .db #0d255 16 | .db #0d255 17 | .db #0d255 18 | .db #0d255 19 | .db #0d255 20 | .db #0d255 21 | .db #0d208 ; :POWER 22 | .db #0d255 23 | .db #0d255 24 | .db #0d255 25 | .db #0d064 ; "@" 26 | .db #0d209 ; :SIZE 27 | .db #0d210 ; :SPELLING 28 | .db #0d211 ; :EMAIL 29 | .db #0d212 ; :PAGE_UP 30 | .db #0d255 31 | .db #0d255 32 | .db #0d255 33 | .db #0d255 34 | .db #0d255 35 | .db #0d255 36 | .db #0d255 37 | .db #0d255 38 | .db #0d096 ; "`" 39 | .db #0d049 ; "1" 40 | .db #0d050 ; "2" 41 | .db #0d051 ; "3" 42 | .db #0d052 ; "4" 43 | .db #0d053 ; "5" 44 | .db #0d054 ; "6" 45 | .db #0d055 ; "7" 46 | .db #0d255 47 | .db #0d255 48 | .db #0d255 49 | .db #0d255 50 | .db #0d255 51 | .db #0d255 52 | .db #0d255 53 | .db #0d255 54 | .db #0d056 ; "8" 55 | .db #0d057 ; "9" 56 | .db #0d048 ; "0" 57 | .db #0d045 ; "-" 58 | .db #0d061 ; "=" 59 | .db #0d008 ; "\b" 60 | .db #0d092 ; "\\" 61 | .db #0d213 ; :PAGE_DOWN 62 | .db #0d255 63 | .db #0d255 64 | .db #0d255 65 | .db #0d255 66 | .db #0d255 67 | .db #0d255 68 | .db #0d255 69 | .db #0d255 70 | .db #0d009 ; "\t" 71 | .db #0d113 ; "q" 72 | .db #0d119 ; "w" 73 | .db #0d101 ; "e" 74 | .db #0d114 ; "r" 75 | .db #0d116 ; "t" 76 | .db #0d121 ; "y" 77 | .db #0d117 ; "u" 78 | .db #0d255 79 | .db #0d255 80 | .db #0d255 81 | .db #0d255 82 | .db #0d255 83 | .db #0d255 84 | .db #0d255 85 | .db #0d255 86 | .db #0d105 ; "i" 87 | .db #0d111 ; "o" 88 | .db #0d112 ; "p" 89 | .db #0d091 ; "[" 90 | .db #0d093 ; "]" 91 | .db #0d059 ; ";" 92 | .db #0d039 ; "'" 93 | .db #0d010 ; "\n" 94 | .db #0d255 95 | .db #0d255 96 | .db #0d255 97 | .db #0d255 98 | .db #0d255 99 | .db #0d255 100 | .db #0d255 101 | .db #0d255 102 | .db #0d214 ; :CAPS_LOCK 103 | .db #0d097 ; "a" 104 | .db #0d115 ; "s" 105 | .db #0d100 ; "d" 106 | .db #0d102 ; "f" 107 | .db #0d103 ; "g" 108 | .db #0d104 ; "h" 109 | .db #0d106 ; "j" 110 | .db #0d255 111 | .db #0d255 112 | .db #0d255 113 | .db #0d255 114 | .db #0d255 115 | .db #0d255 116 | .db #0d255 117 | .db #0d255 118 | .db #0d107 ; "k" 119 | .db #0d108 ; "l" 120 | .db #0d044 ; "," 121 | .db #0d046 ; "." 122 | .db #0d047 ; "/" 123 | .db #0d218 ; :UP 124 | .db #0d219 ; :DOWN 125 | .db #0d221 ; :RIGHT 126 | .db #0d255 127 | .db #0d255 128 | .db #0d255 129 | .db #0d255 130 | .db #0d255 131 | .db #0d255 132 | .db #0d255 133 | .db #0d255 134 | .db #0d215 ; :LEFT_SHIFT 135 | .db #0d122 ; "z" 136 | .db #0d120 ; "x" 137 | .db #0d099 ; "c" 138 | .db #0d118 ; "v" 139 | .db #0d098 ; "b" 140 | .db #0d110 ; "n" 141 | .db #0d109 ; "m" 142 | .db #0d255 143 | .db #0d255 144 | .db #0d255 145 | .db #0d255 146 | .db #0d255 147 | .db #0d255 148 | .db #0d255 149 | .db #0d255 150 | .db #0d217 ; :FN 151 | .db #0d255 152 | .db #0d255 153 | .db #0d032 ; " " 154 | .db #0d255 155 | .db #0d255 156 | .db #0d216 ; :RIGHT_SHIFT 157 | .db #0d220 ; :LEFT 158 | 159 | scancode_table_uppercase: 160 | .db #0d200 ; :MAIN_MENU 161 | .db #0d201 ; :BACK 162 | .db #0d202 ; :PRINT 163 | .db #0d203 ; :F1 164 | .db #0d204 ; :F2 165 | .db #0d205 ; :F3 166 | .db #0d206 ; :F4 167 | .db #0d207 ; :F5 168 | .db #0d255 169 | .db #0d255 170 | .db #0d255 171 | .db #0d255 172 | .db #0d255 173 | .db #0d255 174 | .db #0d255 175 | .db #0d208 ; :POWER 176 | .db #0d255 177 | .db #0d255 178 | .db #0d255 179 | .db #0d064 ; "@" 180 | .db #0d209 ; :SIZE 181 | .db #0d210 ; :SPELLING 182 | .db #0d211 ; :EMAIL 183 | .db #0d212 ; :PAGE_UP 184 | .db #0d255 185 | .db #0d255 186 | .db #0d255 187 | .db #0d255 188 | .db #0d255 189 | .db #0d255 190 | .db #0d255 191 | .db #0d255 192 | .db #0d126 ; "~" 193 | .db #0d033 ; "!" 194 | .db #0d064 ; "@" 195 | .db #0d035 ; "#" 196 | .db #0d036 ; "$" 197 | .db #0d037 ; "%" 198 | .db #0d094 ; "^" 199 | .db #0d038 ; "&" 200 | .db #0d255 201 | .db #0d255 202 | .db #0d255 203 | .db #0d255 204 | .db #0d255 205 | .db #0d255 206 | .db #0d255 207 | .db #0d255 208 | .db #0d042 ; "*" 209 | .db #0d040 ; "(" 210 | .db #0d041 ; ")" 211 | .db #0d095 ; "_" 212 | .db #0d043 ; "+" 213 | .db #0d008 ; "\b" 214 | .db #0d124 ; "|" 215 | .db #0d213 ; :PAGE_DOWN 216 | .db #0d255 217 | .db #0d255 218 | .db #0d255 219 | .db #0d255 220 | .db #0d255 221 | .db #0d255 222 | .db #0d255 223 | .db #0d255 224 | .db #0d009 ; "\t" 225 | .db #0d081 ; "Q" 226 | .db #0d087 ; "W" 227 | .db #0d069 ; "E" 228 | .db #0d082 ; "R" 229 | .db #0d084 ; "T" 230 | .db #0d089 ; "Y" 231 | .db #0d085 ; "U" 232 | .db #0d255 233 | .db #0d255 234 | .db #0d255 235 | .db #0d255 236 | .db #0d255 237 | .db #0d255 238 | .db #0d255 239 | .db #0d255 240 | .db #0d073 ; "I" 241 | .db #0d079 ; "O" 242 | .db #0d080 ; "P" 243 | .db #0d123 ; "{" 244 | .db #0d125 ; "}" 245 | .db #0d058 ; ":" 246 | .db #0d034 ; "\"" 247 | .db #0d010 ; "\n" 248 | .db #0d255 249 | .db #0d255 250 | .db #0d255 251 | .db #0d255 252 | .db #0d255 253 | .db #0d255 254 | .db #0d255 255 | .db #0d255 256 | .db #0d214 ; :CAPS_LOCK 257 | .db #0d065 ; "A" 258 | .db #0d083 ; "S" 259 | .db #0d068 ; "D" 260 | .db #0d070 ; "F" 261 | .db #0d071 ; "G" 262 | .db #0d072 ; "H" 263 | .db #0d074 ; "J" 264 | .db #0d255 265 | .db #0d255 266 | .db #0d255 267 | .db #0d255 268 | .db #0d255 269 | .db #0d255 270 | .db #0d255 271 | .db #0d255 272 | .db #0d075 ; "K" 273 | .db #0d076 ; "L" 274 | .db #0d060 ; "<" 275 | .db #0d062 ; ">" 276 | .db #0d063 ; "?" 277 | .db #0d218 ; :UP 278 | .db #0d219 ; :DOWN 279 | .db #0d221 ; :RIGHT 280 | .db #0d255 281 | .db #0d255 282 | .db #0d255 283 | .db #0d255 284 | .db #0d255 285 | .db #0d255 286 | .db #0d255 287 | .db #0d255 288 | .db #0d215 ; :LEFT_SHIFT 289 | .db #0d090 ; "Z" 290 | .db #0d088 ; "X" 291 | .db #0d067 ; "C" 292 | .db #0d086 ; "V" 293 | .db #0d066 ; "B" 294 | .db #0d078 ; "N" 295 | .db #0d077 ; "M" 296 | .db #0d255 297 | .db #0d255 298 | .db #0d255 299 | .db #0d255 300 | .db #0d255 301 | .db #0d255 302 | .db #0d255 303 | .db #0d255 304 | .db #0d217 ; :FN 305 | .db #0d255 306 | .db #0d255 307 | .db #0d032 ; " " 308 | .db #0d255 309 | .db #0d255 310 | .db #0d216 ; :RIGHT_SHIFT 311 | .db #0d220 ; :LEFT 312 | 313 | scancode_table_control: 314 | .db #0d200 ; :MAIN_MENU 315 | .db #0d201 ; :BACK 316 | .db #0d202 ; :PRINT 317 | .db #0d203 ; :F1 318 | .db #0d204 ; :F2 319 | .db #0d205 ; :F3 320 | .db #0d206 ; :F4 321 | .db #0d207 ; :F5 322 | .db #0d255 323 | .db #0d255 324 | .db #0d255 325 | .db #0d255 326 | .db #0d255 327 | .db #0d255 328 | .db #0d255 329 | .db #0d208 ; :POWER 330 | .db #0d255 331 | .db #0d255 332 | .db #0d255 333 | .db #0d064 ; "@" 334 | .db #0d209 ; :SIZE 335 | .db #0d210 ; :SPELLING 336 | .db #0d211 ; :EMAIL 337 | .db #0d212 ; :PAGE_UP 338 | .db #0d255 339 | .db #0d255 340 | .db #0d255 341 | .db #0d255 342 | .db #0d255 343 | .db #0d255 344 | .db #0d255 345 | .db #0d255 346 | .db #0d096 ; "`" 347 | .db #0d049 ; "1" 348 | .db #0d050 ; "2" 349 | .db #0d027 ; 27 350 | .db #0d028 ; 28 351 | .db #0d029 ; 29 352 | .db #0d030 ; 30 353 | .db #0d031 ; 31 354 | .db #0d255 355 | .db #0d255 356 | .db #0d255 357 | .db #0d255 358 | .db #0d255 359 | .db #0d255 360 | .db #0d255 361 | .db #0d255 362 | .db #0d127 ; 127 363 | .db #0d057 ; "9" 364 | .db #0d048 ; "0" 365 | .db #0d031 ; 31 366 | .db #0d061 ; "=" 367 | .db #0d008 ; "\b" 368 | .db #0d028 ; 28 369 | .db #0d213 ; :PAGE_DOWN 370 | .db #0d255 371 | .db #0d255 372 | .db #0d255 373 | .db #0d255 374 | .db #0d255 375 | .db #0d255 376 | .db #0d255 377 | .db #0d255 378 | .db #0d009 ; "\t" 379 | .db #0d017 ; 17 380 | .db #0d023 ; 23 381 | .db #0d005 ; 5 382 | .db #0d018 ; 18 383 | .db #0d020 ; 20 384 | .db #0d025 ; 25 385 | .db #0d021 ; 21 386 | .db #0d255 387 | .db #0d255 388 | .db #0d255 389 | .db #0d255 390 | .db #0d255 391 | .db #0d255 392 | .db #0d255 393 | .db #0d255 394 | .db #0d009 ; 9 395 | .db #0d015 ; 15 396 | .db #0d016 ; 16 397 | .db #0d027 ; 27 398 | .db #0d029 ; 29 399 | .db #0d059 ; ";" 400 | .db #0d039 ; "'" 401 | .db #0d010 ; "\n" 402 | .db #0d255 403 | .db #0d255 404 | .db #0d255 405 | .db #0d255 406 | .db #0d255 407 | .db #0d255 408 | .db #0d255 409 | .db #0d255 410 | .db #0d214 ; :CAPS_LOCK 411 | .db #0d001 ; 1 412 | .db #0d019 ; 19 413 | .db #0d004 ; 4 414 | .db #0d006 ; 6 415 | .db #0d007 ; 7 416 | .db #0d008 ; 8 417 | .db #0d010 ; 10 418 | .db #0d255 419 | .db #0d255 420 | .db #0d255 421 | .db #0d255 422 | .db #0d255 423 | .db #0d255 424 | .db #0d255 425 | .db #0d255 426 | .db #0d011 ; 11 427 | .db #0d012 ; 12 428 | .db #0d044 ; "," 429 | .db #0d046 ; "." 430 | .db #0d031 ; 31 431 | .db #0d218 ; :UP 432 | .db #0d219 ; :DOWN 433 | .db #0d221 ; :RIGHT 434 | .db #0d255 435 | .db #0d255 436 | .db #0d255 437 | .db #0d255 438 | .db #0d255 439 | .db #0d255 440 | .db #0d255 441 | .db #0d255 442 | .db #0d215 ; :LEFT_SHIFT 443 | .db #0d026 ; 26 444 | .db #0d024 ; 24 445 | .db #0d003 ; 3 446 | .db #0d022 ; 22 447 | .db #0d002 ; 2 448 | .db #0d014 ; 14 449 | .db #0d013 ; 13 450 | .db #0d255 451 | .db #0d255 452 | .db #0d255 453 | .db #0d255 454 | .db #0d255 455 | .db #0d255 456 | .db #0d255 457 | .db #0d255 458 | .db #0d217 ; :FN 459 | .db #0d255 460 | .db #0d255 461 | .db #0d032 ; " " 462 | .db #0d255 463 | .db #0d255 464 | .db #0d216 ; :RIGHT_SHIFT 465 | .db #0d220 ; :LEFT 466 | -------------------------------------------------------------------------------- /lib/tools/generate_cursorx_lookup.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # generate cursorx lookup table using 5 bits for col group and 3 for offset 4 | # Copyright (c) 2019 joshua stein 5 | # 6 | # Permission to use, copy, modify, and distribute this software for any 7 | # purpose with or without fee is hereby granted, provided that the above 8 | # copyright notice and this permission notice appear in all copies. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | # 18 | 19 | # pixels: 01234567012345670123456801234567012345670123456701234567012345670 20 | # col group: | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 21 | # font cell: .....11111.....11111.....11111.....11111.....11111.....11111..... 22 | 23 | File.open("#{__dir__}/../cursorx_lookup.inc", "w+") do |f| 24 | f.puts "; AUTOMATICALLY GENERATED FILE - see tools/generate_cursorx_lookup.rb" 25 | 26 | pcol = 0 27 | 64.times do |x| 28 | col_group = 20 - (pcol / 8) - 1 29 | off = pcol % 8 30 | 31 | v = sprintf("%05b%03b", col_group, off).to_i(2) 32 | 33 | f.puts "\t.db #0x#{sprintf("%02x", v)}\t\t\t; #{sprintf("%08b", v)} - col group #{col_group}, offset #{off}" 34 | 35 | pcol += 5 36 | 37 | if pcol == 160 38 | pcol = 0 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/tools/generate_scancodes.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # generate scancode lookup tables 4 | # Copyright (c) 2019 joshua stein 5 | # 6 | # Permission to use, copy, modify, and distribute this software for any 7 | # purpose with or without fee is hereby granted, provided that the above 8 | # copyright notice and this permission notice appear in all copies. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | # 18 | 19 | META_KEY_BEGIN = 200 20 | 21 | KEYS = [ 22 | :MAIN_MENU, 23 | :BACK, 24 | :PRINT, 25 | :F1, 26 | :F2, 27 | :F3, 28 | :F4, 29 | :F5, 30 | :POWER, 31 | :SIZE, 32 | :SPELLING, 33 | :EMAIL, 34 | :PAGE_UP, 35 | :PAGE_DOWN, 36 | :CAPS_LOCK, 37 | :LEFT_SHIFT, 38 | :RIGHT_SHIFT, 39 | :FN, 40 | :UP, 41 | :DOWN, 42 | :LEFT, 43 | :RIGHT, 44 | ] 45 | 46 | META_KEY_NONE = 255 47 | 48 | UPPERCASES = { 49 | "`" => "~", 50 | "1" => "!", 51 | "2" => "@", 52 | "3" => "#", 53 | "4" => "$", 54 | "5" => "%", 55 | "6" => "^", 56 | "7" => "&", 57 | "8" => "*", 58 | "9" => "(", 59 | "0" => ")", 60 | "-" => "_", 61 | "=" => "+", 62 | "\\" => "|", 63 | "[" => "{", 64 | "]" => "}", 65 | ";" => ":", 66 | "'" => "\"", 67 | "," => "<", 68 | "." => ">", 69 | "/" => "?", 70 | } 71 | 72 | CONTROLS = { 73 | "a" => 1, 74 | "b" => 2, 75 | "c" => 3, 76 | "d" => 4, 77 | "e" => 5, 78 | "f" => 6, 79 | "g" => 7, 80 | "h" => 8, 81 | "i" => 9, 82 | "j" => 10, 83 | "k" => 11, 84 | "l" => 12, 85 | "m" => 13, 86 | "n" => 14, 87 | "o" => 15, 88 | "p" => 16, 89 | "q" => 17, 90 | "r" => 18, 91 | "s" => 19, 92 | "t" => 20, 93 | "u" => 21, 94 | "v" => 22, 95 | "w" => 23, 96 | "x" => 24, 97 | "y" => 25, 98 | "z" => 26, 99 | "3" => 27, 100 | "[" => 27, 101 | "4" => 28, 102 | "\\" => 28, 103 | "5" => 29, 104 | "]" => 29, 105 | "6" => 30, 106 | "7" => 31, 107 | "-" => 31, 108 | "/" => 31, 109 | "8" => 127, 110 | } 111 | 112 | SCANCODES = { 113 | 0 => :MAIN_MENU, 114 | 1 => :BACK, 115 | 2 => :PRINT, 116 | 3 => :F1, 117 | 4 => :F2, 118 | 5 => :F3, 119 | 6 => :F4, 120 | 7 => :F5, 121 | 15 => :POWER, 122 | 19 => "@", 123 | 20 => :SIZE, 124 | 21 => :SPELLING, 125 | 22 => :EMAIL, 126 | 23 => :PAGE_UP, 127 | 32 => "`", 128 | 33 => "1", 129 | 34 => "2", 130 | 35 => "3", 131 | 36 => "4", 132 | 37 => "5", 133 | 38 => "6", 134 | 39 => "7", 135 | 48 => "8", 136 | 49 => "9", 137 | 50 => "0", 138 | 51 => "-", 139 | 52 => "=", 140 | 53 => "\b", # backspace 141 | 54 => "\\", 142 | 55 => :PAGE_DOWN, 143 | 64 => "\t", 144 | 65 => "q", 145 | 66 => "w", 146 | 67 => "e", 147 | 68 => "r", 148 | 69 => "t", 149 | 70 => "y", 150 | 71 => "u", 151 | 80 => "i", 152 | 81 => "o", 153 | 82 => "p", 154 | 83 => "[", 155 | 84 => "]", 156 | 85 => ";", 157 | 86 => "'", 158 | 87 => "\n", 159 | 96 => :CAPS_LOCK, 160 | 97 => "a", 161 | 98 => "s", 162 | 99 => "d", 163 | 100 => "f", 164 | 101 => "g", 165 | 102 => "h", 166 | 103 => "j", 167 | 112 => "k", 168 | 113 => "l", 169 | 114 => ",", 170 | 115 => ".", 171 | 116 => "/", 172 | 117 => :UP, 173 | 118 => :DOWN, 174 | 119 => :RIGHT, 175 | 128 => :LEFT_SHIFT, 176 | 129 => "z", 177 | 130 => "x", 178 | 131 => "c", 179 | 132 => "v", 180 | 133 => "b", 181 | 134 => "n", 182 | 135 => "m", 183 | 144 => :FN, 184 | 147 => " ", 185 | 150 => :RIGHT_SHIFT, 186 | 151 => :LEFT, 187 | } 188 | 189 | File.open("#{__dir__}/../scancodes.inc", "w+") do |scf| 190 | scf.puts "; AUTOMATICALLY GENERATED FILE - see tools/generate_scancodes.rb" 191 | scf.puts "\t.equ\tMETA_KEY_BEGIN,\t#0d#{sprintf("%03d", META_KEY_BEGIN)}" 192 | scf.puts "\t.equ\tMETA_KEY_NONE,\t#0d#{sprintf("%03d", META_KEY_NONE)}" 193 | scf.puts 194 | 195 | 3.times do |x| 196 | if x == 0 197 | scf.puts "scancode_table:" 198 | elsif x == 1 199 | scf.puts 200 | scf.puts "scancode_table_uppercase:" 201 | elsif x == 2 202 | scf.puts 203 | scf.puts "scancode_table_control:" 204 | end 205 | 206 | (0 .. SCANCODES.keys.last).each do |sc| 207 | if k = SCANCODES[sc] 208 | origk = k 209 | if k.is_a?(Symbol) 210 | k = META_KEY_BEGIN + KEYS.index(k) 211 | elsif k.is_a?(String) 212 | k = k.ord 213 | end 214 | raise if !k 215 | 216 | if x == 1 217 | if u = UPPERCASES[origk] 218 | k = u.ord 219 | origk = u 220 | elsif ("a" .. "z").include?(origk) 221 | k = origk.upcase.ord 222 | origk = origk.upcase 223 | end 224 | elsif x == 2 225 | if u = CONTROLS[origk] 226 | k = u 227 | origk = u 228 | end 229 | end 230 | 231 | scf.puts "\t.db #0d#{sprintf("%03d", k)}\t\t; #{origk.inspect}" 232 | else 233 | scf.puts "\t.db #0d#{sprintf("%03d", META_KEY_NONE)}" 234 | end 235 | end 236 | end 237 | end 238 | 239 | File.open("#{__dir__}/../meta_keys.h", "w+") do |mkh| 240 | mkh.puts "/* AUTOMATICALLY GENERATED FILE - see tools/generate_scancodes.rb */" 241 | mkh.puts "#define\tMETA_KEY_BEGIN\t#{META_KEY_BEGIN}" 242 | 243 | KEYS.each_with_index do |k,x| 244 | mkh.puts "#define\tKEY_#{k}\t#{k.length < 3 ? "\t" : ""}#{META_KEY_BEGIN + x}" 245 | end 246 | 247 | mkh.puts 248 | mkh.puts "#define\tMETA_KEY_NONE\t#{META_KEY_NONE}" 249 | end 250 | -------------------------------------------------------------------------------- /lib/tools/hexfont2inc.rb: -------------------------------------------------------------------------------- 1 | # 2 | # convert a hex-exported bitmap font (like from gbdfed) to an asm include file 3 | # Copyright (c) 2019 joshua stein 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any 6 | # purpose with or without fee is hereby granted, provided that the above 7 | # copyright notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | # 17 | 18 | chars = [] 19 | char_size = 0 20 | all_bytes = [] 21 | 22 | if !ARGV[0] 23 | puts "usage: #{$0} " 24 | exit 1 25 | end 26 | 27 | File.open(ARGV[0], "r") do |f| 28 | char = 0 29 | 30 | while f && !f.eof? 31 | line = f.gets 32 | 33 | # 0023:A0E0A0E0A000 34 | if !(m = line.match(/^(....):(.+)$/)) 35 | raise "unexpected format: #{line.inspect}" 36 | end 37 | 38 | char = m[1].to_i(16) 39 | char_size = (m[2].length / 2) 40 | 41 | # A0E0A0E0A000 42 | # -> [ "A0", "e0", "A0", "e0", "A0", "00", "00" ] 43 | bytes = m[2].scan(/(..)/).flatten 44 | 45 | # -> [ 0xa0, 0xe0, 0xa0, 0xe0, 0xa0, 0x00, 0x00 ] 46 | bytes = bytes.map{|c| c.to_i(16) } 47 | 48 | # -> [ 101000000, 11100000, ... ] 49 | # -> [ [ 1, 0, 1, 0, 0, 0, 0, 0 ], [ 1, 1, 1, 0, 0, 0, 0, 0 ], ... ] 50 | bytes = bytes.map{|c| sprintf("%08b", c).split(//).map{|z| z.to_i } } 51 | 52 | # -> [ [ 0, 0, 0, 0, 0, 1, 0, 1 ], [ 0, 0, 0, 0, 0, 1, 1, 1 ], ... ] 53 | bytes = bytes.map{|a| a.reverse } 54 | 55 | # -> [ 0x5, 0x7, ... ] 56 | bytes = bytes.map{|a| a.join.to_i(2) } 57 | 58 | chars[char] = bytes 59 | end 60 | end 61 | 62 | (0 .. 255).each do |c| 63 | if chars[c] && chars[c].any? 64 | print ".db " << chars[c].map{|c| sprintf("#0x%02x", c) }.join(", ") 65 | if c >= 32 && c <= 126 66 | print "\t; #{sprintf("%.3d", c)} - #{c.chr}" 67 | end 68 | print "\n" 69 | else 70 | puts ".db " << char_size.times.map{|c| "#0x00" }.join(", ") 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /lib/tools/relink_packed.rb: -------------------------------------------------------------------------------- 1 | #/usr/bin/env ruby 2 | # 3 | # link, figure out header/code/data sizes, then relink with them packed tightly 4 | # Copyright (c) 2021 joshua stein 5 | # 6 | # Permission to use, copy, modify, and distribute this software for any 7 | # purpose with or without fee is hereby granted, provided that the above 8 | # copyright notice and this permission notice appear in all copies. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | # 18 | 19 | def get_size(area) 20 | File.open(ENV["PROG_MAP"], "r") do |f| 21 | while f && !f.eof? 22 | line = f.gets 23 | # _HEADER0 00000000 000000F9 = 249. bytes (ABS,CON) 24 | if m = line.match(/^#{area} .* (\d+)\. *bytes/) 25 | return m[1].to_i 26 | end 27 | end 28 | end 29 | 30 | raise "can't find #{area} in #{ENV["PROG_MAP"]}" 31 | end 32 | 33 | def sdcc(code_start, data_start) 34 | s = "#{ENV["SDCC"]} --code-loc #{sprintf("0x%04x", code_start)} " + 35 | "--data-loc #{sprintf("0x%04x", data_start)} -o #{ENV["TARGET"]} " + 36 | "#{ARGV.join(" ")}" 37 | puts s 38 | system(s) 39 | end 40 | 41 | base_addr = ENV["BASE_ADDR"].to_i(16) 42 | header_size = 0x1000 43 | code_start = base_addr + header_size 44 | data_start = base_addr + 0x4000 45 | 46 | # link once at a large offset data-loc 47 | sdcc(code_start, data_start) 48 | 49 | header_size = get_size("_HEADER0") 50 | printf "header: %d bytes (0x%04x)\n", header_size, header_size 51 | 52 | code_size = get_size("_CODE") 53 | printf "code: %d bytes (0x%04x)\n", code_size, code_size 54 | 55 | data_size = get_size("_DATA") 56 | printf "data: %d bytes (0x%04x)\n", data_size, data_size 57 | 58 | printf "total: %d bytes (0x%04x)\n", header_size + code_size + data_size, 59 | header_size + code_size + data_size 60 | 61 | code_start = base_addr + header_size 62 | data_start = code_start + code_size 63 | printf "relinking with base: 0x%04x code: 0x%04x data:0x%04x\n", 64 | base_addr, code_start, data_start 65 | 66 | sdcc(code_start, data_start) 67 | -------------------------------------------------------------------------------- /lib/wifi.s: -------------------------------------------------------------------------------- 1 | ; vim:syntax=z8a:ts=8 2 | ; 3 | ; WiFiStation parallel port routines 4 | ; Copyright (c) 2019-2021 joshua stein 5 | ; 6 | ; Permission to use, copy, modify, and distribute this software for any 7 | ; purpose with or without fee is hereby granted, provided that the above 8 | ; copyright notice and this permission notice appear in all copies. 9 | ; 10 | ; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | ; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | ; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | ; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | ; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | ; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | ; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | ; 18 | 19 | .module wifi 20 | 21 | .include "mailstation.inc" 22 | 23 | .area _CODE 24 | 25 | .equ CONTROL_DIR, #0x0a 26 | .equ CONTROL_DIR_OUT, #0xff 27 | .equ CONTROL_DIR_IN, #0 28 | 29 | .equ CONTROL_PORT, #0x9 30 | .equ CONTROL_STATUS_MASK, #0xf0 31 | .equ CONTROL_STROBE_BIT, #0 32 | .equ CONTROL_STROBE, #(1 << CONTROL_STROBE_BIT) 33 | .equ CONTROL_LINEFEED_BIT, #1 34 | .equ CONTROL_LINEFEED, #(1 << CONTROL_LINEFEED_BIT) 35 | .equ CONTROL_INIT, #(1 << 2) 36 | .equ CONTROL_SELECT, #(1 << 3) 37 | 38 | .equ DATA_DIR, #0x2c 39 | .equ DATA_DIR_OUT, #0xff 40 | .equ DATA_DIR_IN, #0 41 | .equ DATA_PORT, #0x2d 42 | 43 | .equ STATUS_PORT, #0x21 44 | .equ STATUS_BUSY, #(1 << 7) 45 | .equ STATUS_ACK, #(1 << 6) 46 | 47 | ; void wifi_init(void); 48 | _wifi_init:: 49 | ; lower control lines 50 | ld a, #CONTROL_DIR_OUT 51 | out (#CONTROL_DIR), a 52 | in a, (#CONTROL_PORT) 53 | and #CONTROL_STATUS_MASK 54 | out (#CONTROL_PORT), a 55 | ret 56 | 57 | ; at idle, lower all control lines 58 | ; writer: reader: 59 | ; raise strobe 60 | ; see high strobe as high busy 61 | ; raise linefeed 62 | ; see high linefeed as high ack 63 | ; write all data pins 64 | ; lower strobe 65 | ; see low strobe as low busy 66 | ; read data 67 | ; lower linefeed 68 | ; see lower linefeed as high ack 69 | 70 | ; int wifi_write(char); -1 on error, 0 on success 71 | _wifi_write:: 72 | push ix 73 | ld ix, #0 74 | add ix, sp 75 | push bc 76 | push de 77 | ld c, 4(ix) ; char to send 78 | ld a, #DATA_DIR_OUT 79 | out (#DATA_DIR), a ; we're sending out 80 | in a, (#CONTROL_PORT) 81 | and #CONTROL_STATUS_MASK 82 | set #CONTROL_STROBE_BIT, a 83 | out (#CONTROL_PORT), a ; raise strobe 84 | ld de, #0xffff 85 | wait_for_ack: 86 | in a, (#STATUS_PORT) 87 | and #STATUS_ACK ; is ack high? 88 | jr nz, got_ack ; yes, break 89 | dec de ; no, de-- 90 | ld a, d 91 | cp #0 92 | jr nz, wait_for_ack 93 | ld a, e 94 | cp #0 95 | jr nz, wait_for_ack 96 | jr abort_send ; de == 0, fail 97 | got_ack: 98 | ld a, c 99 | out (#DATA_PORT), a ; write data 100 | xor a 101 | in a, (#CONTROL_PORT) 102 | and #CONTROL_STATUS_MASK 103 | out (#CONTROL_PORT), a ; lower strobe 104 | ld de, #0xffff 105 | wait_for_final_ack: 106 | in a, (#STATUS_PORT) 107 | and #STATUS_ACK ; is ack low? 108 | jr z, got_final_ack ; yes, break 109 | dec de ; no, de-- 110 | ld a, d 111 | cp #0 112 | jr nz, wait_for_final_ack 113 | ld a, e 114 | cp #0 115 | jr nz, wait_for_final_ack 116 | got_final_ack: 117 | pop de 118 | pop bc 119 | pop ix 120 | ld hl, #0 ; return 0 121 | ret 122 | abort_send: 123 | in a, (#CONTROL_PORT) 124 | and #CONTROL_STATUS_MASK 125 | out (#CONTROL_PORT), a ; lower strobe 126 | pop de 127 | pop bc 128 | pop ix 129 | ld hl, #-1 ; return -1 130 | ret 131 | 132 | 133 | ; int wifi_read(void); -1 on nothing read, >= 0 on success returning char 134 | _wifi_read:: 135 | push ix 136 | ld ix, #0 137 | add ix, sp 138 | push de 139 | ld hl, #-1 ; return -1 unless we read something 140 | in a, (#STATUS_PORT) 141 | and #STATUS_BUSY ; is busy high? 142 | jr z, recv_done ; no, bail 143 | and #STATUS_ACK ; but is ack high too? probably bogus 144 | jr nz, recv_done 145 | ld a, #DATA_DIR_IN 146 | out (#DATA_DIR), a ; we're reading in 147 | in a, (#CONTROL_PORT) 148 | and #CONTROL_STATUS_MASK 149 | set #CONTROL_LINEFEED_BIT, a ; raise linefeed 150 | out (#CONTROL_PORT), a 151 | ld de, #0xffff 152 | wait_for_busy_ack: 153 | in a, (#STATUS_PORT) 154 | and #STATUS_BUSY ; is busy high? 155 | jr z, read_data ; no, break 156 | dec de ; no, de-- 157 | ld a, d 158 | cp #0 159 | jr nz, wait_for_busy_ack 160 | ld a, e 161 | cp #0 162 | jr nz, wait_for_busy_ack 163 | jr recv_done ; de == 0, fail 164 | read_data: 165 | in a, (#DATA_PORT) 166 | ld h, #0 167 | ld l, a 168 | raise_lf: 169 | in a, (#CONTROL_PORT) 170 | and #CONTROL_STATUS_MASK 171 | out (#CONTROL_PORT), a ; lower linefeed 172 | recv_done: 173 | pop de 174 | pop ix 175 | ret 176 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MailStation example program 3 | * Copyright (c) 2019-2021 joshua stein 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "lib/mailstation.h" 23 | 24 | /* ignore first peekkey() if it returns power button */ 25 | unsigned char lastkey = KEY_POWER; 26 | 27 | int process_keyboard(void); 28 | void process_input(unsigned char b); 29 | 30 | int 31 | main(void) 32 | { 33 | screen_init(); 34 | 35 | wifi_init(); 36 | 37 | printf("Hello, World\n"); 38 | 39 | for (;;) { 40 | if (process_keyboard() == KEY_POWER) 41 | break; 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | int 48 | process_keyboard(void) 49 | { 50 | unsigned char b; 51 | 52 | b = peekkey(); 53 | 54 | /* this breaks key-repeat, but it's needed to debounce */ 55 | if (b == 0) 56 | lastkey = 0; 57 | else if (b == lastkey) 58 | b = 0; 59 | else 60 | lastkey = b; 61 | 62 | if (b == 0) 63 | return 0; 64 | 65 | switch (b) { 66 | case KEY_POWER: 67 | delay(100); 68 | powerdown(); 69 | break; 70 | case KEY_F1: 71 | break; 72 | case KEY_MAIN_MENU: 73 | break; 74 | case KEY_PAGE_UP: 75 | break; 76 | case KEY_PAGE_DOWN: 77 | break; 78 | case KEY_UP: 79 | break; 80 | case KEY_DOWN: 81 | break; 82 | case KEY_LEFT: 83 | break; 84 | case KEY_RIGHT: 85 | break; 86 | case KEY_SIZE: 87 | break; 88 | default: 89 | putchar(b); 90 | } 91 | 92 | return b; 93 | } 94 | --------------------------------------------------------------------------------