lived.ch 14.12.2023 { *update, 05.01.2024 } * I noticed some logical mistakes while learning the assembly language * It is corrected now. * It looks it isn't always turn bit 4 on and it's done. It has to be in some cases considered what's already activated it needed location and take that into account too. In other words, it's what's already running + bit 4 BUT NOT IN ALL CASES... EASY! hahaha! C128_TransferCharacterstoRAM Location dec 8192, hex $2000 First 128 uppercase and graphics characters Basic is moved to hex $4000, dec 16384 Activation: lda #$18, sta $02ac (or poke 2604,24) NOTE: Do not use any of high resolution graphic commands after this! { in case you need that, modify the code to transfer to other location, e.g. } { dec 12288, $3000, activation with lda #1c, sta $0a2c, or poke 2604,28 } BANK 14 . 00c00 a9 01 lda #$01 . 00c02 8d 00 ff sta $ff00 BANK 15 . 00c00 a9 01 lda #$00 . 00c02 8d 00 ff sta $ff00 Cursor start location dec 9472, hex $2500 Inverse dec 9984, hex $2700 ---------------------------------- TRANSFER CHARACTERS Instead of @, CURSOR is modified to be an empty box! btw. @ is still alive! ;-) ---------------------------------- Start with SYS 3130 in BASIC after you have entered the code in C128 ML Monitor using A command. A c00 lda #$01 (ENTER) and then so on. {you can list the entries with D command, e.g. D c00 (ENTER) or D c00 c77 (ENTER) } SYS 3130 . 00c00 a9 01 lda #$01 . 00c02 8d 00 ff sta $ff00 . 00c05 a2 00 ldx #$00 . 00c07 ea nop . 00c08 bd 00 d0 lda $d000,x . 00c0b 9d 00 20 sta $2000,x . 00c0e bd ff d0 lda $d0ff,x . 00c11 9d ff 20 sta $20ff,x . 00c14 bd ff d1 lda $d1fe,x . 00c17 9d ff 21 sta $21fe,x . 00c1a bd fd d2 lda $d2fd,x . 00c1d 9d fd 22 sta $22fd,x . 00c20 e8 inx . 00c21 e0 ff cpx #$ff . 00c23 d0 e3 bne $0c08 . 00c25 a9 06 lda #$06 . 00c27 8d 20 d0 sta $d020 . 00c2a a9 07 lda #$07 . 00c2c 85 f1 sta $f1 . 00c2e a9 00 lda #$00 . 00c30 8d 00 ff sta $ff00 . 00c33 a9 18 lda #$18 . 00c35 8d 2c 0a sta $0a2c . 00c38 60 rts . 00c39 ea nop . 00c3a 20 6b 0c jsr $0c6b . 00c3d 20 00 0c jsr $0c00 . 00c40 a9 06 lda #$06 . 00c42 8d 21 d0 sta $d021 . 00c45 ea nop . 00c46 a9 ff lda #$ff . 00c48 8d 00 25 sta $2500 . 00c4b a9 81 lda #$81 . 00c4d 8d 01 25 sta $2501 . 00c50 8d 02 25 sta $2502 . 00c53 8d 03 25 sta $2503 . 00c56 8d 04 25 sta $2504 . 00c59 8d 05 25 sta $2505 . 00c5c 8d 06 25 sta $2506 . 00c5f a9 ff lda #$ff . 00c61 8d 07 25 sta $2507 . 00c64 a9 00 lda #$00 . 00c66 aa tax . 00c67 9d 00 04 sta $0400,x . 00c6a 60 rts . 00c6b ea nop . 00c6c a9 ff lda #$ff . 00c6e 85 d8 sta $d8 . 00c70 a9 3b lda #$3b . 00c72 8d 11 d0 sta $d011 . 00c75 a9 1b lda #$1b . 00c77 8d 11 d0 sta $d011 . 00c7a a9 00 lda #$00 . 00c7c 85 d8 sta $d8 . 00c7e 60 rts Commented version { code looks a bit messy, but i wrote it directly } { in ML Monitor of C128. It's actually pretty clear, haha... } { You can re-order it if you wish to } . 00c00 a9 01 lda #$01 - switch to bank 14 . 00c02 8d 00 ff sta $ff00 - to access characters in ROM . 00c05 a2 00 ldx #$00 - reset counter . 00c07 ea nop - NOPs are here to eat memory for free ;-) . 00c08 bd 00 d0 lda $d000,x - start loading characters . 00c0b 9d 00 20 sta $2000,x - and transfer them to our reserved location . 00c0e bd ff d0 lda $d0ff,x - $2000 or dec 8192 . 00c11 9d ff 20 sta $20ff,x . 00c14 bd ff d1 lda $d1ff,x . 00c17 9d ff 21 sta $21ff,x . 00c1a bd fd d2 lda $d2fd,x . 00c1d 9d fd 22 sta $22fd,x - all 128 (0-127) characters, uppercase plus graphic . 00c20 e8 inx . 00c21 e0 ff cpx #$ff . 00c23 d0 e3 bne $0c08 - loop until done . 00c25 a9 06 lda #$06 - screen color . 00c27 8d 20 d0 sta $d020 . 00c2a a9 07 lda #$07 - text color . 00c2c 85 f1 sta $f1 . 00c2e a9 00 lda #$00 . 00c30 8d 00 ff sta $ff00 - switch back to BANK 15 . 00c33 a9 18 lda #$18 - pointer to our new character location . 00c35 8d 2c 0a sta $0a2c - in RAM (where it can be modified) . 00c38 60 rts - back to $00c40 . 00c39 ea nop . 00c3a 20 6b 0c jsr $0c6b - jump to subroutine to reserve space . 00c3d 20 00 0c jsr $0c00 - when reservation is done, jump to transfer chars . 00c40 a9 06 lda #$06 - screen color . 00c42 8d 21 d0 sta $d021 . 00c45 ea nop . 00c46 a9 ff lda #$ff - transform the CURSOR to a rectangle . 00c48 8d 00 25 sta $2500 - 8 bytes starting at $2500, or dec 9472 . 00c4b a9 81 lda #$81 . 00c4d 8d 01 25 sta $2501 . 00c50 8d 02 25 sta $2502 . 00c53 8d 03 25 sta $2503 . 00c56 8d 04 25 sta $2504 . 00c59 8d 05 25 sta $2505 . 00c5c 8d 06 25 sta $2506 . 00c5f a9 ff lda #$ff . 00c61 8d 07 25 sta $2507 - and done. . 00c64 a9 00 lda #$00 - show it at location 1024 . 00c66 aa tax . 00c67 9d 00 04 sta $0400,x . 00c6a 60 rts - back to BASIC . 00c6b ea nop . 00c6c a9 ff lda #$ff - disable Basic interrupt . 00c6e 85 d8 sta $d8 - or we can't switch to graphic mode . 00c70 a9 3b lda #$3b - switch to highres and back . 00c72 8d 11 d0 sta $d011 - to reserve space. BASIC is now at $4000, not $1c01 as usually . 00c75 a9 1b lda #$1b - WARNING: do not use bitmaps anymore . 00c77 8d 11 d0 sta $d011 - meaning highres graphic commands! . 00c7a a9 00 lda #$00 - turn interrupt on . 00c7c 85 d8 sta $d8 - to be able to switch to new character set . 00c7e 60 rts - back to $00c3d Hint: To modify characters as you wish, use EDASS 128 (or other assembler editors for C128) like this: { you'll need 4 loops to reach 1024 byte for all 128 characters, 128 chars * 8 bytes = 1024 bytes} { or 4x 256 bytes, 4 loops, 1024 bytes transfer } { or just 2 loops to modify first 64 uppercase characters } { or you can bother with zero page, pointers and page increasing } { i preffer this lazy way. it's easy and working fine } { first 64 characters, uppercase, 512 bytes } @abcdefghijklmnopqrstuvwxyz[\]^_ <- you don't see it, but here is SPACE!, $20 or dec 32 ;-) !"#$%&'()*+,-./0123456789:;<=>? charmod = $2000 { 1st 32 characters } ldx# $00 loop1 lda chars1,x sta charmod,x inx cpx #$ff bne loop1 { 2nd 32 characters } ldx# $00 loop2 lda chars2,x sta charmod+255,x inx cpx #$ff bne loop2 etc. for all characters {graphic and inverse uppercase graphics ) ;@ { 1st 32 characters } chars1 .byte $ff,$81,$81,$81,$81,$81,$81,$ff ;a .byte $xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx ;b .byte $xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx ;xx { 2nd 32 characters } chars2 .byte $xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx ;xx .byte $xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx ;xx .byte $xx,$xx,$xx,$xx,$xx,$xx,$xx,$xx etc. Have fun!