
.psx
.create "HelloWorld16BPP.bin", 0x80010000

.macro WRIOW,IOREG,DATA ; Write I/O Port Register Word (A0 = IO_BASE 0x1F800000)
  li t0,DATA      ; T0 = DATA Word
  sw t0,IOREG(a0) ; I/O Port Register Word = T0
.endmacro

; GPU Registers
GP0     equ 0x1810 ; $1F801810..$1F801813 GPU Registers: Write GP0 Commands/Packets (Rendering & VRAM Access)                4B/W
GP1     equ 0x1814 ; $1F801814..$1F801817 GPU Registers: Write GP1 Commands (Display Control)                                4B/W
; I/O Map
IO_BASE equ 0x1F800000 ; I/O Port Base Address ($1F80XXXX)


;.include "LIB/PSX.INC" ; Include PSX Definitions
;.include "LIB/PSX_GPU.INC" ; Include PSX GPU Definitions & Macros

;============
; GPU Macros
;============
.macro WRGP0,COMMAND,PARAMETER                 ; Write GP0 Command/Packet (Rendering & VRAM Access)
  WRIOW GP0,(COMMAND<<24)+(PARAMETER&0xFFFFFF) ; Write GP0 Command/Packet Word
.endmacro

.macro WRGP1,COMMAND,PARAMETER      ; Write GP1 Command (Display Control)
  WRIOW GP1,(COMMAND<<24)+(PARAMETER&0xFFFFFF) ; Write GP1 Command Word
.endmacro
.macro FillRectVRAM,COLOR,X,Y,WIDTH,HEIGHT ; GP0($02) - Fill Rectangle In VRAM
  WRIOW GP0,(0x02<<24)+(COLOR&0xFFFFFF) ; Write GP0 Command Word (Color+Command)
  WRIOW GP0,(Y<<16)+(X&0xFFFF)          ; Write GP0  Packet Word (Top Left Corner:  X Counted In Halfwords, Steps Of $10)
  WRIOW GP0,(HEIGHT<<16)+(WIDTH&0xFFFF) ; Write GP0  Packet Word (Width+Height: Width Counted In Halfwords, Steps Of $10)
.endmacro
GPURESET   equ 0x00 ; GPU Display Control Commands (GP1): $00 - Reset GPU
GPUDRAWM   equ 0xE1 ; GPU Rendering Attributes (GP0): $E1 - Draw Mode Setting (AKA "Texpage")
GPUTEXWIN  equ 0xE2 ; GPU Rendering Attributes (GP0): $E2 - Texture Window Setting
GPUDRAWATL equ 0xE3 ; GPU Rendering Attributes (GP0): $E3 - Set Drawing Area Top Left (X1,Y1)
GPUDRAWABR equ 0xE4 ; GPU Rendering Attributes (GP0): $E4 - Set Drawing Area Bottom Right (X2,Y2)
GPUDRAWOFS equ 0xE5 ; GPU Rendering Attributes (GP0): $E5 - Set Drawing Offset (X,Y)
GPUMASKBIT equ 0xE6 ; GPU Rendering Attributes (GP0): $E6 - Mask Bit Setting
GPURESETCB equ 0x01 ; GPU Display Control Commands (GP1): $01 - Reset Command Buffer
GPUIRQACK  equ 0x02 ; GPU Display Control Commands (GP1): $02 - Acknowledge GPU Interrupt (IRQ1)
GPUDISPEN  equ 0x03 ; GPU Display Control Commands (GP1): $03 - Display Enable
GPUDMA     equ 0x04 ; GPU Display Control Commands (GP1): $04 - DMA Direction / Data Request
GPUVRAM    equ 0x05 ; GPU Display Control Commands (GP1): $05 - Start Of Display Area (In VRAM)
GPUDISPH   equ 0x06 ; GPU Display Control Commands (GP1): $06 - Horizontal Display Range (On Screen)
GPUDISPV   equ 0x07 ; GPU Display Control Commands (GP1): $07 -   Vertical Display Range (On Screen)

   HRES320 equ 0x01 ; Display Mode: Horizontal Resolution 1 320 (Bit 0..1)
   VRES240 equ 0x00 ; Display Mode: Vertical Resolution 240 (Bit 2)
   VRES480 equ 0x04 ; Display Mode: Vertical Resolution 480 (When Vertical Interlace Bit 5 = 1) (Bit 2)
     VNTSC equ 0x00 ; Display Mode: Video Mode NTSC 60Hz (Bit 3)
	 BPP15 equ 0x00 ; Display Mode: Display Area Color Depth 15BPP R5/G5/B5 (Bit 4)
  GPUDISPM   equ 0x08 ; GPU Display Control Commands (GP1): $08 - Display Mode


.macro PrintString,X,Y,WIDTH,HEIGHT,FONT,STRING,LENGTH ; Print Text String To VRAM Using Width,Height Font At X,Y Position
  la a1,FONT   ; A1 = Font Address
  la a2,STRING ; A2 = Text Address
  li t0,LENGTH ; T0 = Number of Text Characters to Print
  li t1,X ; T1 = X Position
  li t2,Y ; T2 = Y Position

DrawChars:
    ; Copy Rectangle (CPU To VRAM): X,Y, Width,Height

    ; Write GP0 Command Word (Command)
    li t3,0xA0<<24 ; T3 = DATA Word	;$a0     send image to frame buffer
    sw t3,GP0(a0) ; I/O Port Register Word = T3

    ; Write GP0  Packet Word (Destination Coord: X Counted In Halfwords)
    sll t3,t2,16 ; T3 = Y<<16
    addu t3,t1 ; T3 = DATA Word (Y<<16)+X
    sw t3,GP0(a0) ; I/O Port Register Word = T3

    ; Write GP0  Packet Word (Width+Height:  Width Counted In Halfwords)
    li t3,(HEIGHT<<16)+WIDTH ; T3 = DATA Word
    sw t3,GP0(a0) ; I/O Port Register Word = T3

    ; Write GP0  Packet Word (Data)
    lbu a3,0(a2) ; A3 = Next Text Character
    li t3,(WIDTH*HEIGHT/2)-1 ; T3 = Data Copy Word Count
    sll a3,7 ; A3 *= 128
    addu a3,a1 ; A3 = Texture RAM Font Offset
CopyTexture:
      lw t4,0(a3) ; T4 = DATA Word
      addiu a3,4  ; A3 += 4 (Delay Slot)
      sw t4,GP0(a0) ; Write GP0 Packet Word
      bnez t3,CopyTexture ; IF (T3 != 0) Copy Texture
      subiu t3,1 ; T3-- (Delay Slot)

    addiu a2,1 ; Increment Text Offset
    addiu t1,WIDTH ; Add Width To X Position
    bnez t0,DrawChars ; Continue to Print Characters
    subiu t0,1 ; Subtract Number of Text Characters to Print (Delay Slot)
.endmacro

.org 0x80010000 ; Entry Point Of Code

;la a0,IO_BASE ; A0 = I/O Port Base Address ($1F80XXXX)
	lui     a0,0x1F80 

; Setup Screen Mode
    ori     t0,r0,0x0                                         ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 104
    sw      t0,0x1814(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 104
    lui     t0,0x300                                          ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 105
    sw      t0,0x1814(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 105
    lui     t0,0x800                                          ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 106
    addiu   t0,0x1                                            ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 106
    sw      t0,0x1814(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 106
    lui     t0,0x6C6                                          ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 107
    addiu   t0,0x260                                          ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 107
    sw      t0,0x1814(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 107
    lui     t0,0x704                                          ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 108
    addiu   t0,0x2018                                         ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 108
	sw      t0,0x1814(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 108

;WRGP1 GPURESET,0  ; 1Write GP1 Command Word (Reset GPU)
;WRGP1 GPUDISPEN,0 ; Write GP1 Command Word (Enable Display)
;WRGP1 GPUDISPM,HRES320+VRES240+BPP15+VNTSC ; Write GP1 Command Word (Set Display Mode: 320x240, 15BPP, NTSC)
;WRGP1 GPUDISPH,0xC60260 ; Write GP1 Command Word (Horizontal Display Range 608..3168)
;WRGP1 GPUDISPV,0x042018 ; Write GP1 Command Word (Vertical Display Range 24..264)

	lui     t0,-0x1F00                                        ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 111
	addiu   t0,0x400                                          ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 111
    sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 111
    lui     t0,-0x1D00                                        ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 112
    sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 112
    lui     t0,-0x1BFC                                        ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 113
    addiu   t0,-0x42C1                                        ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 113
    sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 113
    lui     t0,-0x1B00                                        ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 114
    sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 114

; Setup Drawing Area
;WRGP0 GPUDRAWM,0x000400   ; Write GP0 Command Word (Drawing To Display Area Allowed Bit 10)
;WRGP0 GPUDRAWATL,0x000000 ; Write GP0 Command Word (Set Drawing Area Top Left X1=0, Y1=0)
;WRGP0 GPUDRAWABR,0x03BD3F ; Write GP0 Command Word (Set Drawing Area Bottom Right X2=319, Y2=239)
;WRGP0 GPUDRAWOFS,0x000000 ; Write GP0 Command Word (Set Drawing Offset X=0, Y=0)

    lui     t0,0x200       ;Cmd                                   ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117
    sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117
    li     t0,0x0            ;XY                             ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117
    sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117
	
    lui     t0,0xEF    ;239		                              ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117
    addiu   t0,0x13F   ;319                                   ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117
	sw      t0,0x1810(a0)                                     ; Q:\Sources\16BPP\HelloWorld16BPP.asm line 117

; Clear Screen
;FillRectVRAM 0x000000, 0,0, 319,239 ; Fill Rectangle In VRAM: Color, X,Y, Width,Height

; Print Text
PrintString 128,32, 8,8, FontBlack, Text, 12 ; Print Text String To VRAM Using Width,Height Font At X,Y Position
PrintString 192,96, 8,8, FontRed, Text, 12 ; Print Text String To VRAM Using Width,Height Font At X,Y Position

Loop:
  b Loop
  nop ; Delay Slot

Text:
  .db 0,"Greetings Earthlings!"

.align 4
FontBlack:	
  .incbin "t.fnt"
FontRed:
  .incbin "FontRed8x8.bin"

.close