The source code for this looks like absolute spaghetti, it's difficult to follow and I plan on cleaning that up. I'm sure there are improvements to the structure that I could make.
To use this, all you have to do is copy this source code into its own file, use an include directive with its filename, and then in your main program call "JSR JapaneseScript" and it will do the rest. Updating this to have variable input is easy. Create your desired string in the format described in the code example, load its effective address into A0, then call the subroutine.
This code supports the following features:
* All hiragana characters, including the small versions, and both types of accent marks.
* Periods and commas (quotation marks not implemented yet)
* Automatically moves to the next line if you reach the bottom of the screen. There is currently no error checking for going off the left side of the screen, you have been warned!
* Katakana and kanji are not implemented yet.
Feedback is greatly appreciated. This code is functional but it could be formatted better, so any tips on how to improve readability are greatly appreciated.
Code: Select all
JapaneseScript:
pushall
; GOAL: WRITE A SYLLABLE, MOVE VRAM TO THE RIGHT OF IT, WRITE MODIFIER (IF ANY), MOVE DOWN, REPEAT.
; SMALL HIRAGANA GET WRITTEN BELOW A PARENT SYLLABLE.
; ACCENT MARKS GET WRITTEN TO THE RIGHT OF A SYLLABLE.
;PREP WORK
ClearDataRegs
; D0 = INDEX OF THE CHARACTER WE ARE WRITING TO SCREEN.
; D1 = VRAM ADDRESS
; D2 = THE ACTUAL TILE ADDRESS IN 202.S1 OF THE CHOSEN CHARACTER.
; D3 = SHADOW VRAM ADDRESS USED AS A COMPARATOR FOR REACHING END OF LINE.
;LOAD DATA BLOCK ADDRESSES
LEA TestStringJapanese,A0 ;LOAD THE MESSAGE WE WANT TO TYPE
LEA HIRAGANA_LIST,A1 ;LOAD HIRAGANA TABLE
;PREP VRAM
CLR.W D2 ;RESET D2 FROM THE LAST ITERATION OF THE LOOP.
MOVE.W #FIX_TOPRIGHT-32,D1
MOVE.W #1,$3C0004 ;SET INCREMENT FACTOR
loop_PrintStringJapanese:
MOVE.W D1,$3C0000 ;LOAD STARTING ADDRESS FOR VRAM WRITING
MOVE.B (A0)+,D0 ;GET INDEX OF NEXT CHARACTER TO PRINT
CMP.B #$FF,D0 ;DID WE REACH THE TERMINATOR BYTE?
BEQ EndOfStringJapanese
LSL.B #2,D0 ;WE ARE INDEXING INTO A TABLE OF LONGS SO MULTIPLY BY 4
;OUR MODIFIERS START AT $BC.
CMP.B #$E0,D0
BCC PrintAccentMark ;WE NEED TO PRINT AN ACCENT MARK NOW.
MOVE.L (0,A1,D0),A2 ;GET EFFECTIVE ADDRESS OF THE DESIRED SYLLABLE.
MOVE.W (A2),D2 ;STORE ITS INDEX FROM 202.S1 INTO D2
ADD.W #$3000,D2 ;ADD PALETTE NUMBER.
MOVE.W D2,$3C0002 ;WRITE IT TO THE FIX LAYER. VRAMADDR AUTO INCREMENTS DOWNWARD.
CMP.B #0,D0 ;IS THIS THE DUMMY CHARACTER? IF SO DO NOT ADD $100 TO IT.
BEQ noSecondHalf
ADD.W #$100,D2 ;WE JUST WROTE THE TOP HALF. THE BOTTOM HALF IS ALWAYS $100 TILES AWAY.
noSecondHalf:
MOVE.W D2,$3C0002 ;WRITE THE BOTTOM HALF TO THE FIX LAYER.
ADDQ.W #2,D1 ;ADD 2 TO VRAM ADDRESS.
MOVE.W D1,D3 ;COPY D1 TO D3 TO USE AS BOUNDS CHECKER.
AND.B #$1E,D3
CMP.B #$1E,D3 ;ARE WE AT THE BOTTOM OF THE VISIBLE FIX LAYER?
BEQ NewLineJapanese
BRA loop_PrintStringJapanese
EndOfStringJapanese:
Debug
popall
rts
NewLineJapanese:
SUB.W #$1D,D1
SUB.W #$60,D1
;TODO: ADD BOUNDS CHECKING FOR GOING OFF THE LEFT SIDE.
BRA loop_PrintStringJapanese
PrintAccentMark:
ADD.W #$001E,D1 ;SET VRAM ADDRESS TO THE RIGHT SIDE OF THE CHARACTER WE JUST WROTE.
MOVE.W D1,$3C0000
MOVE.L (0,A1,D0),A2 ;GET EFFECTIVE ADDRESS OF THE DESIRED SYLLABLE.
MOVE.W (A2),D2 ;STORE ITS INDEX FROM 202.S1 INTO D2
ADD.W #$3000,D2 ;ADD PALETTE NUMBER.
MOVE.W D2,$3C0002 ;WRITE IT TO THE FIX LAYER. VRAMADDR AUTO INCREMENTS DOWNWARD.
ADD.W #$0100,D2 ;ADD $100 TO GET TO BOTTOM HALF OF THIS.
MOVE.W D2,$3C0002
SUB.W #$001E,D1 ;CHANGE VRAMADDR BACK TO WHERE WE WERE AS IF NOTHING HAPPENED.
BRA loop_PrintStringJapanese
;THIS WORKS FOR DAKUTEN, MARU, COMMA, AND PERIOD.
;BUG: BLACK BAR LIKE ON THE OVERSCAN APPEARS AFTER THE END OF THE CHARACTER.
; CMP.B #46,D0
; BLT DONTADDMODIFIER ;THIS PART IS NOT NEEDED SINCE THESE GET WRITTEN JUST LIKE NORMAL SYLLABLES.
;CMP.B #55,D0
;BGT ACCENTMARK
TestStringJapanese:
DC.B 10,56,46,22,17,26,0,14,6,2,59,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,255
EVEN
; USAGE:
; THE CHARACTER'S INDEX IN THE TABLE "HIRAGANA_LIST" IS WHAT IS READ FROM THE STRING. THIS SAVES A TON OF DATA OVER TIME.
; ACCENT MARKS ARE TREATED AS THEIR OWN CHARACTER. IT WILL GET WRITTEN AUTOMATICALLY IN THE RIGHT PLACE. PUT THEM AFTER THE CHARACTER YOU WANT TO MODIFY.
; EXAMPLE: KO = 10. GO = 10,56
; THERE IS NO ERROR CHECKING FOR SYLLABLES THAT DON'T USE ACCENT MARKS. IT IS UP TO YOU TO USE THEM CORRECTLY!
; COMMAS AND PERIODS NOT IMPLEMENTED YET.
;CHARACTER CHART: TOP HALF, BOTTOM HALF
;HIRAGANA (BOTTOM HALF = TOP HALF + $0100)
HIRAGANA_LIST:
DC.L DUMMY_HIRAGANA ;0
DC.L A_HIRAGANA ;1
DC.L I_HIRAGANA ;2
DC.L U_HIRAGANA ;3
DC.L E_HIRAGANA ;4
DC.L O_HIRAGANA ;5
DC.L KA_HIRAGANA ;6
DC.L KI_HIRAGANA ;7
DC.L KU_HIRAGANA ;8
DC.L KE_HIRAGANA ;9
DC.L KO_HIRAGANA ;10
DC.L SA_HIRAGANA ;11
DC.L SHI_HIRAGANA ;12
DC.L SU_HIRAGANA ;13
DC.L SE_HIRAGANA ;14
DC.L SO_HIRAGANA ;15
DC.L TA_HIRAGANA ;16
DC.L CHI_HIRAGANA ;17
DC.L TSU_HIRAGANA ;18
DC.L TE_HIRAGANA ;19
DC.L TO_HIRAGANA ;20
DC.L NA_HIRAGANA ;21
DC.L NI_HIRAGANA ;22
DC.L NU_HIRAGANA ;23
DC.L NE_HIRAGANA ;24
DC.L NO_HIRAGANA ;25
DC.L HA_HIRAGANA ;26
DC.L HI_HIRAGANA ;27
DC.L FU_HIRAGANA ;28
DC.L HE_HIRAGANA ;29
DC.L HO_HIRAGANA ;30
DC.L MA_HIRAGANA ;31
DC.L MI_HIRAGANA ;32
DC.L MU_HIRAGANA ;33
DC.L ME_HIRAGANA ;34
DC.L MO_HIRAGANA ;35
DC.L YA_HIRAGANA ;36
DC.L YU_HIRAGANA ;37
DC.L YO_HIRAGANA ;38
DC.L RA_HIRAGANA ;39
DC.L RI_HIRAGANA ;40
DC.L RU_HIRAGANA ;41
DC.L RE_HIRAGANA ;42
DC.L RO_HIRAGANA ;43
DC.L WA_HIRAGANA ;44
DC.L WO_HIRAGANA ;45
DC.L N_HIRAGANA ;46
;DECIMAL 0 THRU DECIMAL 46 ARE FULL-SIZE SYLLABLES AND CAN STAND ALONE.
;TREAT THESE AS "OPCODES" THAT MODIFY THE SYLLABLE BEFORE IT.
;THESE ARE WRITTEN BELOW THE SYLLABLE. NOTHING IS WRITTEN TO THE RIGHT OF THEM.
DC.L SMALL_A_HIRAGANA ;47
DC.L SMALL_I_HIRAGANA ;48
DC.L SMALL_U_HIRAGANA ;49
DC.L SMALL_E_HIRAGANA ;50
DC.L SMALL_O_HIRAGANA ;51
DC.L SMALL_YA_HIRAGANA ;52
DC.L SMALL_YU_HIRAGANA ;53
DC.L SMALL_YO_HIRAGANA ;54
DC.L SMALL_TSU_HIRAGANA ;55 (TECHNICALLY THIS MODIFIES THE SYMBOL AFTER IT BUT THE COMPUTER DOESN'T SEE IT DIFFERENTLY.)
;THESE ARE WRITTEN TO THE RIGHT OF THE SYLLABLE.
DC.L DAKUTEN ;56
DC.L MARU ;57
DC.L JP_COMMA ;58
DC.L JP_PERIOD ;59
DUMMY_HIRAGANA: DC.W $0000 ;PLACEHOLDER FOR CHARACTERS THAT DO NOT USE MODIFIERS
A_HIRAGANA: DC.W $0180
I_HIRAGANA: DC.W $0181
U_HIRAGANA: DC.W $0182
E_HIRAGANA: DC.W $0183
O_HIRAGANA: DC.W $0184
KA_HIRAGANA: DC.W $0185
KI_HIRAGANA: DC.W $0186
KU_HIRAGANA: DC.W $0187
KE_HIRAGANA: DC.W $0188
KO_HIRAGANA: DC.W $0189
SA_HIRAGANA: DC.W $018A
SHI_HIRAGANA: DC.W $018B
SU_HIRAGANA: DC.W $018C
SE_HIRAGANA: DC.W $018D
SO_HIRAGANA: DC.W $018E
TA_HIRAGANA: DC.W $018F
CHI_HIRAGANA: DC.W $0190
TSU_HIRAGANA: DC.W $0191
TE_HIRAGANA: DC.W $0192
TO_HIRAGANA: DC.W $0193
NA_HIRAGANA: DC.W $0194
NI_HIRAGANA: DC.W $0195
NU_HIRAGANA: DC.W $0196
NE_HIRAGANA: DC.W $0197
NO_HIRAGANA: DC.W $0198
HA_HIRAGANA: DC.W $0199
HI_HIRAGANA: DC.W $019A
FU_HIRAGANA: DC.W $019B
HE_HIRAGANA: DC.W $019C
HO_HIRAGANA: DC.W $019D
MA_HIRAGANA: DC.W $019E
MI_HIRAGANA: DC.W $019F
MU_HIRAGANA: DC.W $01A0
ME_HIRAGANA: DC.W $01A1
MO_HIRAGANA: DC.W $01A2
YA_HIRAGANA: DC.W $01A3
YU_HIRAGANA: DC.W $01A4
YO_HIRAGANA: DC.W $01A5
RA_HIRAGANA: DC.W $01A6
RI_HIRAGANA: DC.W $01A7
RU_HIRAGANA: DC.W $01A8
RE_HIRAGANA: DC.W $01A9
RO_HIRAGANA: DC.W $01AA
WA_HIRAGANA: DC.W $01AB
WO_HIRAGANA: DC.W $01AC
N_HIRAGANA: DC.W $01AD
SMALL_A_HIRAGANA: DC.W $01AE
SMALL_I_HIRAGANA: DC.W $01AF
SMALL_U_HIRAGANA: DC.W $01B0
SMALL_E_HIRAGANA: DC.W $01B1
SMALL_O_HIRAGANA: DC.W $01B2
SMALL_YA_HIRAGANA: DC.W $01B3
SMALL_YU_HIRAGANA: DC.W $01B4
SMALL_YO_HIRAGANA: DC.W $01B5
SMALL_TSU_HIRAGANA: DC.W $01B6
DAKUTEN: DC.W $01B7
MARU: DC.W $01B8
JP_LEFT_QUOTE: DC.W $01B9
JP_RIGHT_QUOTE: DC.W $01BA
JP_COMMA: DC.W $01FA
JP_PERIOD: DC.W $01FB