mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-22 14:33:51 +00:00
451 lines
18 KiB
NASM
451 lines
18 KiB
NASM
ORG 04000H
|
|
; LOAD 04000H
|
|
; MSX cartridge header @ 0x4000 - 0x400f
|
|
dw 0x4241
|
|
dw Start
|
|
dw Start
|
|
dw 0,0,0,0,0
|
|
|
|
; ******************************
|
|
; * BIOS STANDARD ROUTINES *
|
|
; ******************************
|
|
|
|
RDSLT: EQU 000CH
|
|
RDVRM: EQU 004AH
|
|
WRTVRM: EQU 004AH
|
|
FILVRM: EQU 0056H
|
|
INIGRP: EQU 0072H
|
|
CHSNS: EQU 009CH
|
|
CHGET: EQU 009FH
|
|
MAPXYC: EQU 0111H
|
|
FETCHC: EQU 0114H
|
|
RSLREG: EQU 0138H
|
|
|
|
; ******************************
|
|
; * WORKSPACE VARIABLES *
|
|
; ******************************
|
|
|
|
GRPCOL: EQU 0F3D9H
|
|
FORCLR: EQU 0F3E9H
|
|
BAKCLR: EQU 0F3EAH
|
|
CGPNT: EQU 0F91FH
|
|
EXPTBL: EQU 0FCC1H
|
|
SLTTBL: EQU 0FCC5H
|
|
|
|
; ******************************
|
|
; * CONTROL CHARACTERS *
|
|
; ******************************
|
|
|
|
CR: EQU 13
|
|
RIGHT: EQU 28
|
|
LEFT: EQU 29
|
|
UP: EQU 30
|
|
DOWN: EQU 31
|
|
|
|
Start:
|
|
CHEDIT: CALL INIT ; Cold start
|
|
CH1: CALL CHRMAG ; Magnify chr
|
|
CALL CHRXY ; Chr coords
|
|
LD D,8 ; Cursor size
|
|
CALL GETKEY ; Get command
|
|
CP "Q" ; Quit
|
|
RET Z ;
|
|
LD HL,CH1 ; Set up return
|
|
PUSH HL ;
|
|
CP "A" ; Adopt
|
|
JP Z,ADOPT ;
|
|
CP CR ; Edit
|
|
JR Z,EDIT ;
|
|
LD C,1 ; C=Offset
|
|
CP RIGHT ; Right
|
|
JR Z,CH2 ;
|
|
LD C,0FFH ;
|
|
CP LEFT ; Left
|
|
JR Z,CH2 ;
|
|
LD C,0F0H ;
|
|
CP UP ; Up
|
|
JR Z,CH2 ;
|
|
LD C,16 ;
|
|
CP DOWN ; Down
|
|
RET NZ ;
|
|
CH2: LD A,(CHRNUM) ; Current chr
|
|
ADD A,C ; Add offset
|
|
LD (CHRNUM),A ; New chr
|
|
RET ;
|
|
|
|
EDIT: CALL DOTXY ; Dot coords
|
|
LD D,2 ; Cursor size
|
|
CALL GETKEY ; Get command
|
|
CP CR ; Quit
|
|
RET Z ;
|
|
LD HL,EDIT ; Set up return
|
|
PUSH HL ;
|
|
LD BC,0FE00H ; AND/OR masks
|
|
CP " " ; Space
|
|
JR Z,ED3 ;
|
|
INC C ; New OR mask
|
|
CP "." ; Dot
|
|
JR Z,ED3 ;
|
|
CP RIGHT ; Right
|
|
JR Z,ED2 ;
|
|
LD C,0FFH ; C=Offset
|
|
CP LEFT ; Left
|
|
JR Z,ED2 ;
|
|
LD C,0F8H ;
|
|
CP UP ; Up
|
|
JR Z,ED2 ;
|
|
LD C,8 ;
|
|
CP DOWN ; Down
|
|
RET NZ ;
|
|
ED2: LD A,(DOTNUM) ; Current dot
|
|
ADD A,C ; Add offset
|
|
AND 63 ; Wrap round
|
|
LD (DOTNUM),A ; New dot
|
|
RET ;
|
|
ED3: CALL PATPOS ; IY->Pattern
|
|
LD A,(DOTNUM) ; Current dot
|
|
PUSH AF ;
|
|
RRCA ;
|
|
RRCA ;
|
|
RRCA ;
|
|
AND 7 ; A=Row
|
|
LD E,A ;
|
|
LD D,0 ; DE=Row
|
|
ADD IY,DE ; IY->Row
|
|
POP AF ;
|
|
AND 7 ; A=Column
|
|
INC A ;
|
|
ED4: RRC B ; AND mask
|
|
RRC C ; OR mask
|
|
DEC A ; Count columns
|
|
JR NZ,ED4 ;
|
|
LD A,(IY+0) ; A=Pattern
|
|
AND B ; Strip old bit
|
|
OR C ; New bit
|
|
LD (IY+0),A ; New pattern
|
|
CALL CHRMAG ; Update magnified
|
|
|
|
CHROUT: CALL PATPOS ; IY->Pattern
|
|
CALL CHRXY ; Get coords
|
|
CALL MAP ; Map
|
|
LD B,8 ; Dot rows
|
|
CO1: PUSH DE ;
|
|
PUSH HL ;
|
|
LD A,8 ; Dot cols
|
|
LD E,(IY+0) ; E=Pattern
|
|
CALL SETROW ; Set row
|
|
POP HL ; HL=CLOC
|
|
POP DE ; D=CMASK
|
|
CALL DOWNP ; Down a pixel
|
|
INC IY ;
|
|
DJNZ CO1 ;
|
|
RET ;
|
|
|
|
CHRMAG: CALL PATPOS ; IY->Pattern
|
|
LD C,191 ; Start X
|
|
LD E,7 ; Start Y
|
|
CALL MAP ; Map
|
|
LD B,8 ; Dot rows
|
|
CM1: LD C,5 ; Row mag
|
|
CM2: PUSH BC ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
LD B,8 ; Dot columns
|
|
LD A,(IY+0) ; A=Pattern
|
|
CM3: RLCA ; Test bit
|
|
PUSH AF ;
|
|
SBC A,A ; 0=00H, 1=FFH
|
|
LD E,A ; E=Mag pattern
|
|
LD A,5 ; Column mag
|
|
CALL SETROW ; Set row
|
|
CALL RIGHTP ; Right a pixel
|
|
CALL RIGHTP ; Skip grid
|
|
POP AF ;
|
|
DJNZ CM3 ;
|
|
POP HL ; HL=CLOC
|
|
POP DE ; D=CMASK
|
|
POP BC ;
|
|
CALL DOWNP ; Down a pixel
|
|
DEC C ;
|
|
JR NZ,CM2 ;
|
|
CALL DOWNP ; Skip grid
|
|
INC IY ;
|
|
DJNZ CM1 ;
|
|
RET ;
|
|
|
|
INIT: LD BC,2048 ; Size
|
|
LD DE,CHRTAB ; Destination
|
|
LD HL,(CGPNT+1) ; Source
|
|
IN1: PUSH BC ;
|
|
PUSH DE ;
|
|
LD A,(CGPNT) ; Slot ID
|
|
CALL RDSLT ; Read chr pattern
|
|
EI ;
|
|
POP DE ;
|
|
POP BC ;
|
|
LD (DE),A ; Put in buffer
|
|
INC DE ;
|
|
INC HL ;
|
|
DEC BC ;
|
|
LD A,B ;
|
|
OR C ;
|
|
JR NZ,IN1 ;
|
|
CALL INIGRP ; SCREEN 2
|
|
LD A,(FORCLR) ; Colour 1
|
|
RLCA ;
|
|
RLCA ;
|
|
RLCA ;
|
|
RLCA ;
|
|
LD C,A ; C=Colour 1
|
|
LD A,(BAKCLR) ; Colour 0
|
|
OR C ; Mix
|
|
LD BC,6144 ; Colour table size
|
|
LD HL,(GRPCOL) ; Colour table
|
|
CALL FILVRM ; Fill colours
|
|
LD HL,177*256+11 ;
|
|
LD BC,0FFH*256+10 ;
|
|
LD E,6 ;
|
|
LD A,17 ;
|
|
CALL GRID ; Draw chr grid
|
|
LD HL,49*256+6 ;
|
|
LD BC,0AAH*256+190 ;
|
|
LD E,6 ;
|
|
LD A,9 ;
|
|
CALL GRID ; Draw mag grid
|
|
LD HL,49*256+48 ;
|
|
LD BC,0FFH*256+190 ;
|
|
LD E,6 ;
|
|
LD A,2 ;
|
|
CALL GRID ; Draw mag box
|
|
XOR A ;
|
|
LD (DOTNUM),A ; Current dot
|
|
LD HL,CHRNUM ;
|
|
LD (HL),A ; Current chr
|
|
IN2: PUSH HL ;
|
|
CALL CHROUT ; Display chr
|
|
POP HL ;
|
|
INC (HL) ; Next chr
|
|
JR NZ,IN2 ; Do 256
|
|
RET ;
|
|
|
|
GRID: PUSH AF ;
|
|
PUSH BC ;
|
|
PUSH HL ;
|
|
CALL MAP ; Map
|
|
POP BC ; B=Len,C=Step
|
|
POP AF ;
|
|
LD E,A ; E=Pattern
|
|
POP AF ; A=Count
|
|
PUSH AF ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
GR1: PUSH AF ;
|
|
PUSH BC ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
LD A,B ; A=Len
|
|
CALL SETROW ; Horizontal line
|
|
POP HL ; HL=CLOC
|
|
POP DE ; D=CMASK
|
|
GR3: CALL DOWNP ; Down a pixel
|
|
DEC C ; Done step?
|
|
JR NZ,GR3 ;
|
|
POP BC ;
|
|
POP AF ; A=Count
|
|
DEC A ; Done lines?
|
|
JR NZ,GR1 ;
|
|
POP HL ; HL=Initial CLOC
|
|
POP DE ; D=Initial CMASK
|
|
POP AF ; A=Count
|
|
GR4: PUSH AF ;
|
|
PUSH BC ;
|
|
PUSH DE ;
|
|
PUSH HL ;
|
|
GR5: LD A,1 ; Line width
|
|
CALL SETROW ; Thin line
|
|
CALL DOWNP ; Down a pixel
|
|
DJNZ GR5 ; Vertical len
|
|
POP HL ; HL=CLOC
|
|
POP DE ; D=CMASK
|
|
GR6: CALL RIGHTP ; Right a pixel
|
|
DEC C ; Done step?
|
|
JR NZ,GR6 ;
|
|
POP BC ;
|
|
POP AF ; A=Count
|
|
DEC A ; Done lines?
|
|
JR NZ,GR4 ;
|
|
RET ;
|
|
|
|
MAP: LD B,0 ; X MSB
|
|
LD D,B ; Y MSB
|
|
CALL MAPXYC ; Map coords
|
|
CALL FETCHC ; HL=CLOC
|
|
LD D,A ; D=CMASK
|
|
RET ;
|
|
|
|
RIGHTP: RRC D ; Shift CMASK
|
|
RET NC ; NC=Same cell
|
|
RP1: PUSH BC ;
|
|
LD BC,8 ; Offset
|
|
ADD HL,BC ; HL=Next cell
|
|
POP BC ;
|
|
RET ;
|
|
|
|
DOWNP: INC HL ; CLOC down
|
|
LD A,L ;
|
|
AND 7 ; Select pixel row
|
|
RET NZ ; NZ=Same cell
|
|
PUSH BC ;
|
|
LD BC,00F8H ; Offset
|
|
ADD HL,BC ; HL=Next cell
|
|
POP BC ;
|
|
RET ;
|
|
|
|
SETROW: PUSH BC ;
|
|
LD B,A ; B=Count
|
|
SE1: CALL RDVRM ; Get old pattern
|
|
SE2: LD C,A ; C=Old
|
|
LD A,D ; A=CMASK
|
|
CPL ; AND mask
|
|
AND C ; Strip old bit
|
|
RLC E ; Shift pattern
|
|
JR NC,SE3 ; NC=0 Pixel
|
|
OR D ; Set 1 Pixel
|
|
SE3: DEC B ; Finished?
|
|
JR Z,SE4 ;
|
|
RRC D ; CMASK right
|
|
JR NC,SE2 ; NC=Same cell
|
|
CALL WRTVRM ; Update cell
|
|
CALL RP1 ; Next cell
|
|
JR SE1 ; Start again
|
|
SE4: CALL WRTVRM ; Update cell
|
|
POP BC ;
|
|
RET ;
|
|
|
|
DOTXY: LD A,(DOTNUM) ; Current dot
|
|
PUSH AF ;
|
|
AND 7 ; Column
|
|
RLCA ;
|
|
LD C,A ; C=Col*2
|
|
RLCA ; A=Col*4
|
|
ADD A,C ; A=Col*6
|
|
ADD A,191 ; Grid atart
|
|
LD C,A ; C=X coord
|
|
POP AF ;
|
|
AND 38H ; Row*8
|
|
RRCA ;
|
|
LD E,A ; E=Row*4
|
|
RRCA ; A=Row*2
|
|
ADD A,E ; A=Row*6
|
|
ADD A,7 ; Grid start
|
|
LD E,A ; E=Y coord
|
|
RET ;
|
|
|
|
CHRXY: LD A,(CHRNUM) ; Current chr
|
|
PUSH AF ;
|
|
CALL MULT11 ; Column*11
|
|
ADD A,12 ; Grid start
|
|
LD C,A ; C=X coord
|
|
POP AF ;
|
|
RRCA ;
|
|
RRCA ;
|
|
RRCA ;
|
|
RRCA ;
|
|
CALL MULT11 ; Row*11
|
|
ADD A,8 ; Grid start
|
|
LD E,A ; E=Y coord
|
|
RET ;
|
|
|
|
MULT11: AND 0FH ;
|
|
LD D,A ; D=N
|
|
RLCA ;
|
|
LD B,A ; B=N*2
|
|
RLCA ;
|
|
RLCA ; A=N*8
|
|
ADD A,B ;
|
|
ADD A,D ; A=N*11
|
|
RET ;
|
|
|
|
PATPOS: LD A,(CHRNUM) ; Current chr
|
|
LD L,A ;
|
|
LD H,0 ; HL=Chr
|
|
ADD HL,HL ;
|
|
ADD HL,HL ;
|
|
ADD HL,HL ; HL=Chr*8
|
|
EX DE,HL ; DE=Chr*8
|
|
LD IY,CHRTAB ; Patterns
|
|
ADD IY,DE ; IY->Pattern
|
|
RET ;
|
|
|
|
GETKEY: LD B,0 ; Cursor flag
|
|
GE1: PUSH BC ; C=X coord
|
|
PUSH DE ; E=Y coord
|
|
CALL INVERT ; Flip cursor
|
|
POP DE ;
|
|
POP BC ;
|
|
INC B ; Flip flag
|
|
LD HL,8000 ; Blink rate
|
|
GE2: CALL CHSNS ; Check KEYBUF
|
|
JR NZ,GE3 ; NZ=Got key
|
|
DEC HL ;
|
|
LD A,H ;
|
|
OR L ;
|
|
JR NZ,GE2 ;
|
|
JR GE1 ; Time for cursor
|
|
GE3: BIT 0,B ; Cursor state
|
|
CALL NZ,INVERT ; Remove cursor
|
|
JP CHGET ; Collect character
|
|
|
|
INVERT: PUSH DE ;
|
|
CALL MAP ; Map coords
|
|
POP AF ; A=Cursor size
|
|
LD B,A ; B=Rows
|
|
LD E,A ; E=Cols
|
|
IV1: PUSH DE ;
|
|
PUSH HL ;
|
|
IV2: CALL RDVRM ; Old pattern
|
|
XOR D ; Flip a bit
|
|
CALL WRTVRM ; Put it back
|
|
CALL RIGHTP ; Right a pixel
|
|
DEC E ;
|
|
JR NZ,IV2 ;
|
|
POP HL ; HL=CLOC
|
|
POP DE ; D=CMASK
|
|
CALL DOWNP ; Down a pixel
|
|
DJNZ IV1 ;
|
|
RET ;
|
|
|
|
ADOPT: LD BC,2048 ; Size
|
|
LD DE,0EB80H ; Destination
|
|
LD (CGPNT+1),DE ;
|
|
LD HL,CHRTAB ; Source
|
|
LDIR ; Copy up high
|
|
CALL RSLREG ; Read PSLOT reg
|
|
RLCA ;
|
|
RLCA ;
|
|
AND 3 ; Select Page 3
|
|
LD C,A ;
|
|
LD B,0 ; BC=Page 3 PSLOT#
|
|
LD HL,EXPTBL ; Expanders
|
|
ADD HL,BC ;
|
|
BIT 7,(HL) ; PSLOT expanded?
|
|
JR Z,AD1 ; A=Normal
|
|
LD HL,SLTTBL ; Secondary regs
|
|
ADD HL,BC ;
|
|
LD A,(HL) ; A=Secondary reg
|
|
RLCA ;
|
|
RLCA ;
|
|
RLCA ;
|
|
RLCA ;
|
|
AND 0CH ; A=Page 3 SSLOT#
|
|
OR C ; Mix Page 3 PSLOT#
|
|
SET 7,A ; A=Slot ID
|
|
AD1: LD (CGPNT),A ;
|
|
RET ;
|
|
|
|
CHRNUM: DEFB 0 ; Current chr
|
|
DOTNUM: DEFB 0 ; Current dot
|
|
CHRTAB: DEFS 2048 ; Patterns to EAA2H
|
|
|
|
END
|