Aquí está de nuevo mi rutina de SC1 a 64 columnas, esta vez haciendo uso de las interrupciones en modo IM2 del Z80, que aunque no es tan conocido como el IM1, si que es cierto que permite un mayor control por parte del usuario. ¡Ahora ya no se desperdicia ni un ciclo de la CPU!
Here's again my SC1-64 columns; but this time making use of the IM2 Z80 interrupt mode, not common; but very powerful because it leaves full control to the user. There's no CPU cycles wasted! ;------------------------------------------------------
;
; Description: Creates a SC1 based 64 columns mode by mixing two VRAM pages
;
; The new VRAM map is:
; 0000-07FF : Pattern table 1
; 0800-0FFF : Pattern table 2
; 1400-16FF : Name table 1
; 1800-1AFF : Name table 2
;
; Color, sprites & palette (MSX2) tables addresses are untouched
;
; NOTE: IM2 is used
;
;------------------------------------------------------
.bios
.page 1
.rom
.start MAIN
RG2SAV equ $F3E1
RG4SAV equ $F3E3
MAIN: ; Initializes SC1 with 15,1,1 colors & 32 columns
ld a,32
ld [$F3AF],a
ld a,15
ld [$F3E9],a
ld a,1
ld [$F3EA],a
ld [$F3EB],a
call INIT32
; fills both name tables with spaces (prolly useless)
ld hl,$1400
ld bc,$0700
ld a,32
call FILVRM
; dump to VRAM a 4 pixels right shifted font, based on the old one
ld hl,$0800+32*8
call SETWRT
ld hl,FONT4x8
ld bc,768
@@LOOP: ld a,[hl]
and $F0
rrca
rrca
rrca
rrca
out ($98),a
inc hl
dec bc
ld a,b
or c
jr nz,@@LOOP
; dump the font to VRAM
ld hl,FONT4x8
ld de,$0000+32*8
ld bc,768
call LDIRVM
; Sets active name table to address $1400
ld bc,$0502
call WRTVDP
; installs interupt hook
call INSTALLISR
; prints an example text
ld hl,TXT1
ld de,$0000 ; X(0-63)Y(0-23)
call PUTS
@@HANG: jp @@HANG
;------------------------------------------------------
;
; Description: Prints a string
; Input: D = coord. X (0-63), E = coord. Y (0-23)
; Output: nothing
; Modifies: AF,HL,DE,BC
;
;------------------------------------------------------
PUTS: push hl
ld h,0
ld l,e ; Y
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl ; Y*32
ld b,$14
ld a,d
sra a
ld c,a ; X\2
add hl,bc ; HL=NAME table position
call SETWRT
ex de,hl ; DE=VRAM
pop hl ; HL=TXT1
ld b,2 ; prints even & odd positions
@@LOOP2: push hl
@@LOOP1: ld a,[hl]
or a
jr z,@@FINTXT
out ($98),a ; outputs even char
inc hl
ld a,[hl]
or a
jr z,@@FINTXT
inc hl
jr @@LOOP1
@@FINTXT: ld hl,$400 ; switch to odd chars
add hl,de
call SETWRT
pop hl
inc hl
djnz @@LOOP2
ret
;
; Interrupt routine
;
ISR: push af
in a,[$99]
bit 7,a
jr z,@@NOVDP
push bc
ld b,5
ld a,[VALUE]
inc a
ld [VALUE],a
; sets flag to 0-1 values
and 1
jr z,@@NOPAGE2
inc b
@@NOPAGE2: out ($99),a
ld [RG4SAV],a ; not needed at all
ld a,$84
; sets active pattern table
out ($99),a
ld a,b
out ($99),a
ld [RG2SAV],a ; not needed at all
ld a,$82
; sets active name table
out ($99),a
pop bc
@@NOVDP: pop af
ei
reti
;
; Installs interrupt hook
;
INSTALLISR: di
ld hl,INTVECTAB
ld e,l
ld d,h
inc de
ld [hl],ISRJUMP>>8
ld bc,256
ldir
ld a,$C3
ld [ISRJUMP],a
ld hl,ISR
ld [ISRJUMP+1],hl
ld a,INTVECTAB>>8
ld i,a
im 2
ei
ret
;
; Example text
;
TXT1: DB "En un agujero en el suelo, vivia un hobbit."
DB " No un agujero humedo, sucio, repugnante, "
DB "con restos de gusanos y olor a fango, ni "
DB "tampoco un agujero seco, desnudo y arenoso, "
DB "sin nada en que sentarse o que comer: era un "
DB "agujero-hobbit, y eso significa comodidad. Tenia"
DB " una puerta redonda, perfecta como un ojo de "
DB "buey, pintada de verde, con una manilla de bronce"
DB " dorada y brillante, justo en el medio. La puerta"
DB " se abria a un vestibulo cilindrico, como un tunel:"
DB " un tunel muy comodo, sin humos, con paredes "
DB "revestidas de madera y suelos enlosados y "
DB "alfombrados, provisto de sillas barnizadas, y "
DB "montones y montones de perchas para sombreros "
DB "y abrigos; el hobbit era aficionado a las visitas.",0
;
; Guess what?. It's a 4x8 font...
;
FONT4x8:
DB $00,$00,$00,$00,$00,$00,$00,$00
DB $40,$40,$40,$40,$40,$00,$40,$00
DB $A0,$A0,$00,$00,$00,$00,$00,$00
DB $A0,$A0,$F0,$A0,$F0,$A0,$A0,$00
DB $40,$E0,$80,$40,$20,$E0,$40,$00
DB $A0,$20,$40,$40,$40,$80,$A0,$00
DB $40,$A0,$40,$80,$C0,$A0,$50,$00
DB $40,$40,$00,$00,$00,$00,$00,$00
DB $40,$80,$80,$80,$80,$80,$40,$00
DB $40,$20,$20,$20,$20,$20,$40,$00
DB $00,$00,$A0,$40,$A0,$00,$00,$00
DB $00,$00,$40,$E0,$40,$00,$00,$00
DB $00,$00,$00,$00,$00,$20,$40,$00
DB $00,$00,$00,$E0,$00,$00,$00,$00
DB $00,$00,$00,$00,$00,$00,$40,$00
DB $20,$20,$40,$40,$40,$80,$80,$00
DB $40,$A0,$A0,$A0,$A0,$A0,$40,$00
DB $40,$C0,$40,$40,$40,$40,$E0,$00
DB $40,$A0,$20,$40,$80,$80,$E0,$00
DB $40,$A0,$20,$40,$20,$A0,$40,$00
DB $A0,$A0,$A0,$E0,$20,$20,$20,$00
DB $E0,$80,$80,$C0,$20,$A0,$40,$00
DB $40,$A0,$80,$C0,$A0,$A0,$40,$00
DB $E0,$20,$20,$40,$40,$40,$40,$00
DB $40,$A0,$A0,$40,$A0,$A0,$40,$00
DB $40,$A0,$A0,$60,$20,$A0,$40,$00
DB $00,$00,$00,$40,$00,$00,$40,$00
DB $00,$00,$00,$20,$00,$20,$40,$00
DB $00,$20,$40,$80,$40,$20,$00,$00
DB $00,$00,$E0,$00,$E0,$00,$00,$00
DB $00,$80,$40,$20,$40,$80,$00,$00
DB $40,$A0,$A0,$20,$40,$00,$40,$00
DB $40,$A0,$A0,$C0,$80,$A0,$40,$00
DB $40,$A0,$A0,$E0,$A0,$A0,$A0,$00
DB $C0,$A0,$A0,$C0,$A0,$A0,$C0,$00
DB $40,$A0,$80,$80,$80,$A0,$40,$00
DB $C0,$A0,$A0,$A0,$A0,$A0,$C0,$00
DB $E0,$80,$80,$C0,$80,$80,$E0,$00
DB $E0,$80,$80,$C0,$80,$80,$80,$00
DB $40,$A0,$80,$A0,$A0,$A0,$40,$00
DB $A0,$A0,$A0,$E0,$A0,$A0,$A0,$00
DB $40,$40,$40,$40,$40,$40,$40,$00
DB $20,$20,$20,$20,$20,$A0,$40,$00
DB $A0,$A0,$A0,$C0,$A0,$A0,$A0,$00
DB $80,$80,$80,$80,$80,$80,$E0,$00
DB $A0,$E0,$E0,$A0,$A0,$A0,$A0,$00
DB $E0,$A0,$A0,$A0,$A0,$A0,$A0,$00
DB $40,$A0,$A0,$A0,$A0,$A0,$40,$00
DB $C0,$A0,$A0,$C0,$80,$80,$80,$00
DB $40,$A0,$A0,$A0,$A0,$C0,$20,$00
DB $C0,$A0,$A0,$C0,$A0,$A0,$A0,$00
DB $40,$A0,$80,$40,$20,$A0,$40,$00
DB $E0,$40,$40,$40,$40,$40,$40,$00
DB $A0,$A0,$A0,$A0,$A0,$A0,$60,$00
DB $A0,$A0,$A0,$A0,$A0,$A0,$40,$00
DB $A0,$A0,$A0,$A0,$E0,$E0,$A0,$00
DB $A0,$A0,$A0,$40,$A0,$A0,$A0,$00
DB $A0,$A0,$A0,$40,$40,$40,$40,$00
DB $E0,$20,$20,$40,$80,$80,$E0,$00
DB $60,$40,$40,$40,$40,$40,$60,$00
DB $80,$80,$40,$40,$40,$20,$20,$00
DB $60,$20,$20,$20,$20,$20,$60,$00
DB $40,$A0,$00,$00,$00,$00,$00,$00
DB $00,$00,$00,$00,$00,$00,$E0,$00
DB $40,$20,$00,$00,$00,$00,$00,$00
DB $00,$00,$00,$40,$A0,$A0,$60,$00
DB $00,$80,$80,$C0,$A0,$A0,$40,$00
DB $00,$00,$00,$60,$80,$80,$60,$00
DB $00,$20,$20,$60,$A0,$A0,$40,$00
DB $00,$00,$00,$60,$A0,$C0,$60,$00
DB $00,$20,$40,$E0,$40,$40,$40,$00
DB $00,$00,$00,$40,$A0,$60,$C0,$00
DB $00,$80,$80,$C0,$A0,$A0,$A0,$00
DB $00,$00,$40,$00,$40,$40,$40,$00
DB $00,$00,$40,$00,$40,$40,$80,$00
DB $00,$80,$A0,$C0,$A0,$A0,$A0,$00
DB $00,$40,$40,$40,$40,$40,$40,$00
DB $00,$00,$00,$A0,$E0,$A0,$A0,$00
DB $00,$00,$00,$E0,$A0,$A0,$A0,$00
DB $00,$00,$00,$40,$A0,$A0,$40,$00
DB $00,$00,$00,$C0,$A0,$C0,$80,$00
DB $00,$00,$00,$40,$A0,$60,$20,$00
DB $00,$00,$00,$A0,$C0,$80,$80,$00
DB $00,$00,$00,$20,$40,$20,$C0,$00
DB $00,$40,$40,$E0,$40,$40,$40,$00
DB $00,$00,$00,$A0,$A0,$A0,$60,$00
DB $00,$00,$00,$A0,$A0,$A0,$40,$00
DB $00,$00,$00,$A0,$A0,$E0,$A0,$00
DB $00,$00,$00,$A0,$40,$40,$A0,$00
DB $00,$00,$00,$A0,$A0,$40,$C0,$00
DB $00,$00,$00,$E0,$60,$80,$E0,$00
DB $20,$40,$40,$80,$40,$40,$20,$00
DB $40,$40,$40,$40,$40,$40,$40,$00
DB $80,$40,$40,$20,$40,$40,$80,$00
DB $40,$F0,$20,$00,$00,$00,$00,$00
;
; RAM variables
;
.page 3
INTVECTAB: DS 257
VALUE: DS 1
DUMMY: DS $BF ; OFFSET, DON'T MOVE, DON'T CHANGE!!!
ISRJUMP: DS 3