Kitomas

nes startup and the other assembly stuff ver 0

Sep 9th, 2022
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;shared version 0
  2. .FEATURE c_comments
  3. .import _main
  4.  
  5. ;boilerplate stuff and linker gen. symbols
  6.     .export   __STARTUP__ : absolute = 1 ; Mark as startup
  7.     .import   __RAM_START__, __RAM_SIZE__
  8.  
  9. .include  "zeropage.inc"
  10.  
  11. ;-MACROS-
  12.  
  13. ;increment 16-bit value
  14. .macro inc16 address
  15.     .local skip
  16.     inc address
  17.     bne skip
  18.     inc address + 1
  19. skip:
  20. .endmacro
  21. ;decrement 16-bit value
  22. .macro dec16 address
  23.     .local skip
  24.     dec address
  25.     bne skip
  26.     dec address+1
  27. skip:
  28. .endmacro
  29.  
  30.  
  31. ;far branches
  32.   ;carry flag
  33. .macro bcc_far address
  34.     bcs * + 5
  35.     jmp address
  36. .endmacro
  37. .macro bcs_far address
  38.     bcc * + 5
  39.     jmp address
  40. .endmacro
  41.  
  42.   ;zero flag
  43. .macro beq_far address
  44.     bne * + 5
  45.     jmp address
  46. .endmacro
  47. .macro bne_far address
  48.     beq * + 5
  49.     jmp address
  50. .endmacro
  51.  
  52.   ;negative flag
  53. .macro bmi_far address
  54.     bpl * + 5
  55.     jmp address
  56. .endmacro
  57. .macro bpl_far address
  58.     bmi * + 5
  59.     jmp address
  60. .endmacro
  61.  
  62.   ;overflow flag
  63. .macro bvc_far address
  64.     bvs * + 5
  65.     jmp address
  66. .endmacro
  67. .macro bvs_far address
  68.     bvc * + 5
  69.     jmp address
  70. .endmacro
  71.  
  72. ;loads 16-bit number into a 16-bit register
  73. .macro LoadWord value,   low_byte,high_byte
  74.     lda #<value
  75.     sta low_byte
  76.     lda #>value
  77.     sta high_byte
  78. .endmacro
  79. ;loads 16-bit number into a 16-bit register (in big endian)
  80. .macro LoadWordRev value,   low_byte, high_byte
  81.     lda #>value
  82.     sta low_byte
  83.     lda #<value
  84.     sta high_byte
  85. .endmacro
  86.  
  87. ;-GLOBAL LABELS-
  88.  
  89. ;-ram oriented-
  90.  
  91. nameTableBuffer   = $0100 ;->019F;  160 bytes
  92. stackStart        = $01A0 ;->01FF;   96 bytes
  93.  
  94. ;-hardware oriented-
  95.  
  96. CONTROLLER1 = $4016
  97. JOYPAD1     = $4016 ;alias
  98. CONTROLLER2 = $4017
  99. JOYPAD2     = $4017
  100.  
  101. ;ppu registers
  102. PPUCTRL   = $2000 ;>  write
  103. ;7  bit  0
  104. ;---- ----
  105. ;VPHB SINN
  106. ;|||| ||||
  107. ;|||| ||++- Base nametable address
  108. ;|||| ||    (0 = $2000; 1 = $2400; 2 = $2800; 3 = $2C00)
  109. ;|||| |+--- VRAM address increment per CPU read/write of PPUDATA
  110. ;|||| |     (0: add 1, going across; 1: add 32, going down)
  111. ;|||| +---- Sprite pattern table address for 8x8 sprites
  112. ;||||       (0: $0000; 1: $1000; ignored in 8x16 mode)
  113. ;|||+------ Background pattern table address (0: $0000; 1: $1000)
  114. ;||+------- Sprite size (0: 8x8 pixels; 1: 8x16 pixels – see PPU OAM#Byte 1)
  115. ;|+-------- PPU master/slave select
  116. ;|          (0: read backdrop from EXT pins; 1: output color on EXT pins)
  117. ;+--------- Generate an NMI at the start of the
  118. ;           vertical blanking interval (0: off; 1: on)
  119. PPUMASK   = $2001 ;>  write
  120. ;7  bit  0
  121. ;---- ----
  122. ;BGRs bMmG
  123. ;|||| ||||
  124. ;|||| |||+- Greyscale (0: normal color, 1: produce a greyscale display)
  125. ;|||| ||+-- 1: Show background in leftmost 8 pixels of screen, 0: Hide
  126. ;|||| |+--- 1: Show sprites in leftmost 8 pixels of screen, 0: Hide
  127. ;|||| +---- 1: Show background
  128. ;|||+------ 1: Show sprites
  129. ;||+------- Emphasize red (green on PAL/Dendy)
  130. ;|+-------- Emphasize green (red on PAL/Dendy)
  131. ;+--------- Emphasize blue     
  132. PPUSTATUS = $2002 ;<  read     
  133. OAMADDR   = $2003 ;>  write    
  134. OAMDATA   = $2004 ;<> read/write   
  135. PPUSCROLL = $2005 ;>> write 2x 
  136. PPUADDR   = $2006 ;>> write 2x 
  137. PPUDATA   = $2007 ;<> read/write   
  138. OAMDMA    = $4014 ;>  write     (do this during vblank)
  139.  
  140.  
  141. ;palette stuff (there are 25 total palette colors registers)
  142. PPUPAL_BGUNI = $3F00 ;        universal background color
  143. PPUPAL_BG0   = $3F01 ;->$3F03 background palette 0
  144.     PPUPAL_BG0_A = PPUPAL_BG0
  145.     PPUPAL_BG0_B = PPUPAL_BG0 + 1
  146.     PPUPAL_BG0_C = PPUPAL_BG0 + 2
  147. PPUPAL_BG1   = $3F05 ;->$3F07 background palette 1
  148.     PPUPAL_BG1_A = PPUPAL_BG1
  149.     PPUPAL_BG1_B = PPUPAL_BG1 + 1
  150.     PPUPAL_BG1_C = PPUPAL_BG1 + 2
  151. PPUPAL_BG2   = $3F09 ;->$3F0B background palette 2
  152.     PPUPAL_BG2_A = PPUPAL_BG2
  153.     PPUPAL_BG2_B = PPUPAL_BG2 + 1
  154.     PPUPAL_BG2_C = PPUPAL_BG2 + 2
  155. PPUPAL_BG3   = $3F0D ;->$3F0F background palette 3
  156.     PPUPAL_BG3_A = PPUPAL_BG3
  157.     PPUPAL_BG3_B = PPUPAL_BG3 + 1
  158.     PPUPAL_BG3_C = PPUPAL_BG3 + 2
  159. PPUPAL_SP0   = $3F10 ;->$3F13 sprite palette 0
  160.     PPUPAL_SP0_A = PPUPAL_SP0
  161.     PPUPAL_SP0_B = PPUPAL_SP0 + 1
  162.     PPUPAL_SP0_C = PPUPAL_SP0 + 2
  163. PPUPAL_SP1   = $3F14 ;->$3F17 sprite palette 1
  164.     PPUPAL_SP1_A = PPUPAL_SP1
  165.     PPUPAL_SP1_B = PPUPAL_SP1 + 1
  166.     PPUPAL_SP1_C = PPUPAL_SP1 + 2
  167. PPUPAL_SP2   = $3F18 ;->$3F1B sprite palette 2
  168.     PPUPAL_SP2_A = PPUPAL_SP2
  169.     PPUPAL_SP2_B = PPUPAL_SP2 + 1
  170.     PPUPAL_SP2_C = PPUPAL_SP2 + 2
  171. PPUPAL_SP3   = $3F1C ;->$3F1F sprite palette 3
  172.     PPUPAL_SP3_A = PPUPAL_SP3
  173.     PPUPAL_SP3_B = PPUPAL_SP3 + 1
  174.     PPUPAL_SP3_C = PPUPAL_SP3 + 2
  175. ;basic html color names with aliases (ntsc grayscale=$0d,$2d,$00,$10,$3d,$30)
  176. PPUPAL_WHITE     = $30 ;#$FFFFFF
  177. PPUPAL_SILVER    = $10 ;#$C0C0C0
  178. PPUPAL_GRAYHI    = $10 ;^^
  179. PPUPAL_GRAY      = $00 ;#$808080
  180. PPUPAL_GRAYLO    = $00 ;^^
  181. PPUPAL_BLACK     = $0D ;#$000000
  182. PPUPAL_RED       = $16 ;#$FF0000
  183. PPUPAL_REDHI     = $16 ;^^
  184. PPUPAL_MAROON    = $06 ;#$800000
  185. PPUPAL_REDLO     = $06 ;^^
  186. PPUPAL_YELLOW    = $37 ;#$FFFF00 (not that useful for ntsc)
  187. PPUPAL_YELLOWHI  = $37 ;^^
  188. PPUPAL_OLIVE     = $28 ;#$808000
  189. PPUPAL_YELLOWLO  = $28 ;^^
  190. PPUPAL_LIME      = $2a ;#$00FF00
  191. PPUPAL_GREENHI   = $2a ;^^
  192. PPUPAL_GREEN     = $1a ;#$008000
  193. PPUPAL_GREENLO   = $1a ;^^
  194. PPUPAL_AQUA      = $2c ;#$00FFFF
  195. PPUPAL_CYANHI    = $2c ;^^
  196. PPUPAL_TEAL      = $1c ;#$008080
  197. PPUPAL_CYANLO    = $1c ;^^
  198. PPUPAL_BLUE      = $12 ;#$0000FF
  199. PPUPAL_BLUEHI    = $12 ;^^
  200. PPUPAL_NAVY      = $01 ;#$000080
  201. PPUPAL_BLUELO    = $01 ;^^
  202. PPUPAL_FUCHSIA   = $24 ;#$FF00FF
  203. PPUPAL_MAGENTAHI = $24 ;^^
  204. PPUPAL_PURPLE    = $04 ;#$800080
  205. PPUPAL_MAGENTALO = $04 ;^^
  206. ;$0d = 00 = 0
  207. ;$2d = 4e = 78
  208. ;$00 = 65 = 101
  209. ;$10 = ae = 174
  210. ;$3d = b7 = 183
  211. ;$30 = ff = 255
  212.  
  213.  
  214. ;nametable stuff
  215. PPU_NAMETABLE_A = $2000
  216. PPU_NAMETABLE_B = $2400
  217. PPU_NAMETABLE_C = $2800
  218. PPU_NAMETABLE_D = $2C00
  219. ;attribute table byte layout:
  220. ;7654 3210
  221. ;|||| ||++- Color bits 3-2 for top left quadrant of this byte
  222. ;|||| ++--- Color bits 3-2 for top right quadrant of this byte
  223. ;||++------ Color bits 3-2 for bottom left quadrant of this byte
  224. ;++-------- Color bits 3-2 for bottom right quadrant of this byte
  225. PPU_ATTRTABLE0 = $23C0
  226. PPU_ATTRTABLE1 = $27C0
  227. PPU_ATTRTABLE2 = $2BC0
  228. PPU_ATTRTABLE3 = $2FC0
  229.  
  230.  
  231. ;apu registers (</> xxxx xxxx = read/write bits7654 3210)
  232. ;Pulse 1 channel (> write)
  233. APU_PULSE1_0        = $4000 ;> DDLC.NNNN  Duty, loop envelope/disable length counter, constant volume, envelope period/volume
  234. APU_PULSE1_1        = $4001 ;> EPPP.NSSS  Sweep unit: enabled, period, negative, shift count
  235. APU_PULSE1_2        = $4002 ;> LLLL.LLLL  Timer low
  236. APU_PULSE1_3        = $4003 ;> LLLL.LHHH  Length counter load, timer high (also resets duty and starts envelope)
  237. ;Pulse 2 channel (> write)
  238. APU_PULSE2_0        = $4004 ;> DDLC.NNNN  Duty, loop envelope/disable length counter, constant volume, envelope period/volume
  239. APU_PULSE2_1        = $4005 ;> EPPP.NSSS  Sweep unit: enabled, period, negative, shift count
  240. APU_PULSE2_2        = $4006 ;> LLLL.LLLL  Timer low
  241. APU_PULSE2_3        = $4007 ;> LLLL.LHHH  Length counter load, timer high (also resets duty and starts envelope)
  242.  
  243. ;Triangle channel (> write)
  244. APU_TRIANGLE_0      = $4008 ;> CRRR.RRRR  Length counter disable/linear counter control, linear counter reload value
  245. APU_TRIANGLE_1      = $400A ;> LLLL.LLLL  Timer low
  246. APU_TRIANGLE_2      = $400B ;> LLLL.LHHH  Length counter load, timer high (also reloads linear counter)
  247.  
  248. ;Noise channel (> write)
  249. APU_NOISE_0         = $400C ;> --LC.NNNN  Loop envelope/disable length counter, constant volume, envelope period/volume
  250. APU_NOISE_1         = $400E ;> L---.PPPP  Loop noise, noise period
  251. APU_NOISE_2         = $400F ;> LLLL.L---  Length counter load (also starts envelope)
  252.  
  253. ;DMC channel (> write)
  254. APU_DMC_CONTROL     = $4010 ;> IL--.FFFF  IRQ enable, loop sample, frequency index
  255. APU_DMC_DIRECT_LOAD = $4011 ;> -DDD.DDDD  Direct load
  256. APU_DMC_ADDRESS     = $4012 ;> AAAA.AAAA  Sample address %11AAAAAA.AA000000
  257. APU_DMC_LENGTH      = $4013 ;> LLLL.LLLL  Sample length  %0000LLLL.LLLL0001
  258.  
  259. ;general registers
  260. APU_CONTROL         = $4015 ;> ---D NT21  Control: DMC enable, length counter enables: noise, triangle, pulse 2, pulse 1 (> write)
  261. APU_STATUS          = $4015 ;< IF-D NT21  Status: DMC interrupt, frame interrupt, length counter status: noise, triangle, pulse 2, pulse 1 (< read)
  262. APU_FRAME_COUNTER   = $4017 ;> SD-- ----  Frame counter: 5-frame sequence, disable frame interrupt (> write)
  263.  
  264. .segment "HEADER"
  265.  
  266. ;iNES header for nrom mapper
  267.     .byte "NES",$1a ; Constant; "File signature,MS-DOS EOF"
  268.     .byte $02       ; Size of PRG ROM in 16kB units (1 or 2 for NROM-128 or NROM-256 respectively)
  269.     .byte $01       ; Same as above, but for CHR ROM in 8kB units
  270.     .byte %00000001 ; Flags 6  (see below); mapper 0, vertical mirroring
  271.     .byte %00000000 ; Flags 7  (see below); mapper 0
  272.     .byte $00       ; Flags 8  (see below)
  273.     .byte $00       ; Flags 9  (see below)
  274.     .byte $00       ; Flags 10 (see below)
  275.     .byte 0,0,0,0,0 ; Padding/unused bytes
  276.  
  277. ;No trainer is used, so no bytes need to be added (or is that an nes2.0 feature? I forget)
  278.  
  279. ;FLAGS 6:
  280. ;========
  281. ;76543210
  282. ;||||||||
  283. ;|||||||+- Mirroring: 0: horizontal (vertical arrangement) (CIRAM A10 = PPU A11)
  284. ;|||||||              1: vertical (horizontal arrangement) (CIRAM A10 = PPU A10)
  285. ;||||||+-- 1: Cartridge contains battery-backed PRG RAM ($6000-7FFF) or other persistent memory
  286. ;|||||+--- 1: 512-byte trainer at $7000-$71FF (stored before PRG data)
  287. ;||||+---- 1: Ignore mirroring control or above mirroring bit; instead provide four-screen VRAM
  288. ;++++----- Lower nybble of mapper number
  289.  
  290. ;FLAGS 7:
  291. ;========
  292. ;76543210
  293. ;||||||||
  294. ;|||||||+- VS Unisystem
  295. ;||||||+-- PlayChoice-10 (8KB of Hint Screen data stored after CHR data)
  296. ;||||++--- If equal to 2, flags 8-15 are in NES 2.0 format
  297. ;++++----- Upper nybble of mapper number
  298.  
  299. ;FLAGS 8:
  300. ;76543210
  301. ;||||||||
  302. ;++++++++- PRG RAM size
  303.  
  304. ;FLAGS 9:
  305. ;76543210
  306. ;||||||||
  307. ;|||||||+- TV system (0: NTSC; 1: PAL)
  308. ;+++++++-- Reserved, set to zero
  309.  
  310. ;FLAGS 10:
  311. ;76543210
  312. ;  ||  ||
  313. ;  ||  ++- TV system (0: NTSC; 2: PAL; 1/3: dual compatible)
  314. ;  |+----- PRG RAM ($6000-$7FFF) (0: present; 1: not present)
  315. ;  +------ 0: Board has no bus conflicts; 1: Board has bus conflicts
  316.  
  317. .segment "ZEROPAGE"
  318.  
  319. .export _fcounterTOT,_fcounterNLG,_fcounterLAG
  320. .export _joypadState,_joypadState1,_joypadState2
  321. .export _randomNum,_randomNuml,_randomNumh
  322. .export _fstatus,_ppuctrl,_ppumask
  323. .export _scroll,_scrollX,_scrollY
  324.  
  325. scratch:              .res 13
  326. fcounter:             .res 3   ;global frame counters
  327. _fcounterTOT  = fcounter       ;^^total frames   (0-> 59)
  328. _fcounterNLG  = fcounter+1     ;^^non-lag frames (0-> 59)
  329. _fcounterLAG  = fcounter+2     ;^^lag frames     (0->255)
  330. r16a:                 .res 3   ;register 16 a
  331. r16al        = r16a            ;^^
  332. r16ah        = r16a+1          ;^^
  333. swap         = r16a+2          ;^^(very) temporary scratch space
  334. r16b:                 .res 2   ;register 16 b
  335. r16bl        = r16b            ;^^
  336. r16bh        = r16b+1          ;^^
  337. r16c:                 .res 2   ;register 16 c
  338. r16cl        = r16c            ;^^
  339. r16ch        = r16c+1          ;^^
  340. _joypadState:         .res 2   ;last controller reads
  341. _joypadState1 = _joypadState   ;^^
  342. _joypadState2 = _joypadState+1 ;^^
  343. _randomNum:           .res 2   ;current pseudorandomly generated number
  344. _randomNuml   = _randomNum     ;^^
  345. _randomNumh   = _randomNum+1   ;^^
  346. ;frame status:
  347. ;bit 7=main loop finished?
  348. ;6=do nametable upload?
  349. _fstatus:             .res 1
  350. _ppuctrl:             .res 1   ;copies of ppu registers (which are normally write only)
  351. _ppumask:             .res 1   ;^^
  352. _scroll:              .res 2   ;scroll state
  353. _scrollX      = _scroll        ;^^
  354. _scrollY      = _scroll+1      ;^^
  355.  
  356.  
  357. ;i couldn't get OAMBuffer to just be = to 0x200 in c
  358. ;so now these are all a #define fight me
  359. .segment "NAMETABLE_BUF"
  360. ;.export _nametableBuffer
  361. _nametableBuffer:   .res 160
  362. .segment "OAM_BUF"
  363. ;.export _OAMBuffer
  364. _OAMBuffer:         .res 256  ;OAM_Entry* (typedef struct array)
  365. ;//attributes:
  366. ;//76543210
  367. ;//||||||||
  368. ;//||||||++- Palette (4 to 7) of sprite
  369. ;//|||+++--- Unimplemented (read 0)
  370. ;//||+------ Priority (0: in front of background; 1: behind background)
  371. ;//|+------- Flip sprite horizontally
  372. ;//+-------- Flip sprite vertically
  373. .segment "APU_BUF"
  374. ;.export _APUBuffer
  375. _APUBuffer:         .res 256
  376.  
  377. .segment "BSS"
  378. ;.export _highMemory
  379. ;_highMemory:        .res 768
  380.  
  381. ;1 page for cc65 param stack
  382.  
  383. .segment  "STARTUP"
  384.  
  385. .export   _reset ;void (void)
  386.  
  387. _reset:
  388.     sei                     ;enable 'ignore irq?' bit
  389.     cld                     ;clear decimal mode
  390.     ldx #%01000000          ;disable apu frame irq
  391.     stx APU_FRAME_COUNTER   ;^^
  392.     ldx #$ff                ;set up stack
  393.     txs                     ;^^
  394.     inx                     ;x=0
  395.     stx PPUCTRL             ;disable nmi
  396.     stx PPUMASK             ;disable rendering (start fblank)
  397.     stx APU_DMC_CONTROL     ;disable dmc irqs
  398.     bit PPUSTATUS           ;init vblank flag to known state
  399.     jsr _spin               ;wait for 1st vblank
  400. @clearMemoryLoop:           ;flush ram
  401.     lda #0                  ;^^
  402.     sta $0000,x             ;^^
  403.     sta $0100,x             ;^^
  404.     ;sta $0200,x            ;^^(oam buffer handled separately)
  405.     sta $0300,x             ;^^
  406.     sta $0400,x             ;^^
  407.     sta $0500,x             ;^^
  408.     sta $0600,x             ;^^
  409.     sta $0700,x             ;^^
  410.     lda #$ff                ;^^#$ff for oam so that things start off screen
  411.     sta _OAMBuffer,x        ;^^
  412.     inx                     ;^^
  413.     bne @clearMemoryLoop    ;^^
  414.     stx OAMADDR             ;OAMADDR=0 bc i use OAMDMA instead
  415.     lda #<(__RAM_START__ + __RAM_SIZE__ -1) ;set cc65 argument stack pointer
  416.     sta sp                                  ;^^
  417.     lda #>(__RAM_START__ + __RAM_SIZE__ -1) ;^^(remove -1 if things go wack)
  418.     sta sp+1                                ;^^
  419.    
  420.     lda #$aa                ;seed rng
  421.     sta _randomNuml         ;^^
  422.     sta _randomNumh         ;^^
  423.     lda #%10000000          ;initialize frame status to 'finished'
  424.     sta _fstatus            ;^^
  425.    
  426.     jsr _spin               ;wait for 2nd vsync
  427.     lda #%00011110          ;enable sprites & background (stop fblank)
  428.     sta _ppumask            ;^^
  429.     sta PPUMASK             ;^^
  430.     lda #%10010000          ;enable nmi; patt. table: sprite=left, background=right
  431.     sta _ppuctrl            ;^^
  432.     sta PPUCTRL             ;^^
  433.     cli                     ;reenable irq
  434.     jmp _main               ;jump to c main
  435.  
  436. .segment "CODE"
  437.  
  438. .export _vblank,_spin
  439. .export _toIntS,_toIntU
  440. .export _random8,_random16
  441. .export _getButtons
  442. .export _putPalBackground,_putPalSprite
  443. .export _cos,_sin
  444.  
  445. _vblank:
  446.     lda #0              ;for zeroing out frame counters
  447.     ldx #60             ;for frame compares
  448.     inc _fcounterTOT    ;inc total frames count and/or reset
  449.     cpx _fcounterTOT    ;^^
  450.     bne @incFCountTOT   ;^^
  451.     sta _fcounterTOT    ;^^reset if 60 frames elapsed since last reset
  452. @incFCountTOT:         
  453.     bit _fstatus        ;if game loop hasn't finished, exit nmi early
  454.     bmi @doVBlank       ;^^(game loop finished = bit 7 true)
  455.     inc _fcounterLAG    ;inc amount of lag frames (this can roll over lol)
  456.     jmp @skipVBlank     ;exit nmi
  457. @doVBlank:             
  458.     sta _fcounterLAG    ;game loop finished before nmi; reset lag frames
  459.     inc _fcounterNLG    ;inc no lag frames count and/or reset
  460.     cpx _fcounterNLG    ;^^
  461.     bne @incFCountNLG   ;^^
  462.     sta _fcounterNLG    ;^^reset if 60 frames elapsed since last reset
  463.     lda _fstatus        ;reset 'main loop finished' flag
  464.     and #%01111111      ;^^
  465.     sta _fstatus        ;^^
  466. @incFCountNLG:
  467.     sta _fcounterLAG    ;reset lag frames
  468.     lda _ppumask        ;start fblank
  469.     and #%11100111      ;^^
  470.     sta _ppumask        ;^^
  471.     sta PPUMASK         ;^^
  472.    
  473.     ;upload things to vram
  474.     bit _fstatus
  475.     bvc @skipNametableUpload ;if bit 6 of _fstatus set, upload nametable
  476.     ;do nametable upload stuff here
  477.     @skipNametableUpload:
  478.     lda #>_OAMBuffer    ;upload OAMBuffer to actual OAM
  479.     sta OAMDMA          ;^^
  480.     lda _ppuctrl        ;send ppuctrl's new state to the real ppu register
  481.     sta PPUCTRL         ;^^
  482.    
  483.     lda _ppumask        ;stop fblank
  484.     ora #%00011000      ;^^
  485.     sta _ppumask        ;^^
  486.     sta PPUMASK         ;^^
  487. @skipVBlank:
  488. _irq: ;lmao
  489.     rti
  490.  
  491. _spin: ;void (void)
  492.     bit PPUSTATUS   ;did vblank happen? (bit 7=1)
  493.     bpl _spin       ;if not, go back
  494.     rts
  495.  
  496. ;turns fixed point number with 6 bits of fraction to int
  497. _toIntU: ;uint16_t (uint16_t)
  498.     ldy #3
  499.     bpl _toIntU_start   ;always branch
  500. _toIntS: ;int16_t (int16_t)
  501.     ldy #2
  502. _toIntU_start:
  503.     stx swap
  504.     bit swap
  505.     bpl @posNumber
  506.     dey
  507. @posNumber:
  508.     lsr swap        ;unrolled loop
  509.     ror            
  510.     lsr swap       
  511.     ror            
  512.     lsr swap       
  513.     ror            
  514.     lsr swap       
  515.     ror            
  516.     lsr swap       
  517.     ror            
  518.     lsr swap       
  519.     ror            
  520.     dey            
  521.     bne @negNumber 
  522.     tay             ;bit extension if negative
  523.     lda #%11111100  ;^^
  524.     ora swap        ;^^
  525.     sta swap        ;^^
  526.     tya             ;^^
  527. @negNumber:        
  528.     ldx swap       
  529.     rts            
  530.  
  531. ;8-bit xorshift prng
  532. ;source: https://gist.github.com/bhickey/0de228c02cc60b5965582d2d946d8c38
  533. _random8: ;uint8_t (void)
  534.     lda _randomNuml
  535.     asl
  536.     eor _randomNuml
  537.     sta _randomNuml
  538.     lsr
  539.     eor _randomNuml
  540.     sta _randomNuml
  541.     asl
  542.     asl
  543.     eor _randomNuml
  544.     sta _randomNuml
  545.     rts
  546.  
  547. ;16-bit xorshift prng
  548. ;(gonna be honest, this routine is a black box that i
  549. ;don't fully understand)
  550. ;source: https://codebase64.org/doku.php?id=base:16bit_xorshift_random_generator
  551. _random16: ;uint16_t (void)
  552.     lda _randomNumh
  553.     lsr    
  554.     lda _randomNuml
  555.     ror    
  556.     eor _randomNumh
  557.     sta _randomNumh ; high part of x ^= x << 7 done
  558.     ror             ; A has now x >> 9 and high bit comes from low byte
  559.     eor _randomNumh
  560.     sta _randomNuml ; x ^= x >> 9 and the low part of x ^= x << 7 done
  561.     eor _randomNumh
  562.     sta _randomNumh ; x ^= x << 8 done 
  563.     tax             ;set up __fastcall__ return
  564.     lda _randomNuml ;^^
  565.     rts
  566.  
  567. ;most of this yoinked from nesdev iirc
  568. ;this populates joypadState 1&2 with current controller state
  569. _getButtons: ;U_Reg16 (void)
  570.     ;set up poll
  571.     lda #$01         ;start refreshing controller(s) state
  572.     sta JOYPAD1      ;^^
  573.     sta _joypadState2 ;player2r=1 so carry bit after 8th button read is 1
  574.     lsr              ;stop refreshing controller(s) state (a=0 now)
  575.     sta JOYPAD1      ;^^
  576. @readLoop:
  577.     lda JOYPAD1      ;bit 0 from JOYPAD1 -> carry flag
  578.     lsr              ;^^
  579.     rol _joypadState1 ;controller 1 read buffer <- carry flag
  580.     lda JOYPAD2      ;bit 0 from JOYPAD2 -> carry flag
  581.     lsr              ;^^
  582.     rol _joypadState2 ;controller 2 read buffer <- carry flag
  583.     bcc @readLoop    ;once player1r rotates 8 times, carry = 1
  584.     ;lda _joypadState1 ;set up __fastcall__ return
  585.     ;ldx _joypadState2 ;^^(low byte=player 1; high=player 2)
  586.     rts
  587.  
  588.  
  589. _putString:
  590.     rts
  591. _putPalColor: ;void (uint8_t index,uint8_t color)
  592. ;tbd overhaul palette buffer, fstatus, so all of that happens
  593. ;during vblank, and have separate routines
  594. _putPalBackground: ;void (const uint8_t*)
  595.     bit PPUSTATUS
  596.     ldy #>PPUPAL_BGUNI
  597.     sty PPUADDR
  598.     ldy #<PPUPAL_BGUNI
  599.     sty PPUADDR
  600.     ldy #0
  601.     beq paletteCopy ;branch always
  602. _putPalSprite: ;void (const uint8_t*)
  603.     bit PPUSTATUS
  604.     ldy #>PPUPAL_SP0
  605.     sty PPUADDR
  606.     ldy #<PPUPAL_SP0
  607.     sty PPUADDR
  608.     ldy #0
  609. paletteCopy:
  610.     sta r16al
  611.     stx r16ah
  612. @loop:
  613.     lda (r16al),y   ;partially unrolled loop
  614.     sta PPUDATA     ;^^(loops 4 times instead of 16)
  615.     iny
  616.     lda (r16al),y
  617.     sta PPUDATA
  618.     iny
  619.     lda (r16al),y
  620.     sta PPUDATA
  621.     iny
  622.     lda (r16al),y
  623.     sta PPUDATA
  624.     iny
  625.     cpy #16
  626.     bne @loop
  627.     rts
  628.  
  629. ;fixed point sin/cos fastcall function (radians)
  630. ;takes unsigned 16-bit, returns signed 16 bit
  631. ;uses 6 bits of fraction
  632. ;2pi=402=110.010010
  633. ;cos(x)=sin(x-.5pi)=sin(x+1.5pi)
  634. _cos: ;int16_t (uint16_t)
  635.     COSADD=95;(302-256)
  636.     clc         ;add 302, or ~1.5pi (46+256)
  637.     adc #COSADD ;^^(a circle seems to deform at that actually,
  638.     bcc _sin    ;^^but seems to work after adding another .25pi.)
  639.     inx         ;^^increment for high byte
  640. _sin: ;int16_t (uint16_t)
  641.     sta r16al   ;dividend
  642.     stx r16ah   ;^^
  643.     lda #<$0192 ;divisor ($192=402=146+256)
  644.     sta r16bl   ;^^
  645.     lda #>$0192 ;^^
  646.     sta r16bh   ;^^
  647.     ;division code yoinked from (bc i'm too dumb to make my own):
  648.     ;https://codebase64.org/doku.php?id=base:16bit_division_16-bit_result
  649.    ;r16a=dividend; r16b=divisor; r16c=remainder result=swap
  650.     lda #0      ;preset remainder to 0
  651.     sta r16cl
  652.     sta r16ch
  653.     ldx #16     ;repeat for each bit: ...
  654. @divloop:
  655.     asl r16al   ;dividend lb & hb*2, msb -> Carry
  656.     rol r16ah  
  657.     rol r16cl   ;remainder lb & hb * 2 + msb from carry
  658.     rol r16ch
  659.     lda r16cl
  660.     sec
  661.     sbc r16bl   ;substract divisor to see if it fits in
  662.     tay         ;lb result -> Y, for we may need it later
  663.     lda r16ch
  664.     sbc r16bh
  665.     bcc @skip   ;if carry=0 then divisor didn't fit in yet
  666.     sta r16ch   ;else save substraction result as new remainder,
  667.     sty r16cl  
  668.     inc swap    ;and INCrement result cause divisor fit in 1 times
  669. @skip:
  670.     dex
  671.     bne @divloop
  672.     ;;
  673.     lda r16cl               ;add location of lookup table to offset
  674.     clc                     ;^^
  675.     adc #<sin_table         ;^^
  676.     sta r16cl               ;^^
  677.     lda r16ch               ;^^high byte
  678.     adc #>sin_table         ;^^
  679.     sta r16ch               ;^^
  680.     ldx #0                  ;init extended sign to 0
  681.     lda (r16cl,x)           ;
  682.     bpl @no_sign_extension  ;if low byte is negative, extend sign of high byte to $ff
  683.     dex ;x=#%11111111       ;^^
  684. @no_sign_extension:        
  685.     rts                    
  686.  
  687. .segment "RODATA"
  688.  
  689. sin_table:;00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F
  690.     .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ;0000
  691.     .byte $10,$11,$12,$13,$14,$15,$16,$17,$17,$18,$19,$1a,$1b,$1c,$1d,$1e ;0010
  692.     .byte $1f,$20,$20,$21,$22,$23,$24,$25,$25,$26,$27,$28,$29,$29,$2a,$2b ;0020
  693.     .byte $2c,$2c,$2d,$2e,$2e,$2f,$30,$30,$31,$32,$32,$33,$34,$34,$35,$35 ;0030
  694.     .byte $36,$36,$37,$37,$38,$38,$39,$39,$3a,$3a,$3b,$3b,$3b,$3c,$3c,$3c ;0040
  695.     .byte $3d,$3d,$3d,$3e,$3e,$3e,$3e,$3f,$3f,$3f,$3f,$3f,$3f,$40,$40,$40 ;0050
  696.     .byte $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$3f,$3f,$3f ;0060
  697.     .byte $3f,$3f,$3f,$3e,$3e,$3e,$3e,$3d,$3d,$3d,$3c,$3c,$3c,$3b,$3b,$3b ;0070
  698.     .byte $3a,$3a,$39,$39,$38,$38,$37,$37,$36,$36,$35,$35,$34,$34,$33,$32 ;0080
  699.     .byte $32,$31,$31,$30,$2f,$2f,$2e,$2d,$2c,$2c,$2b,$2a,$29,$29,$28,$27 ;0090
  700.     .byte $26,$25,$25,$24,$23,$22,$21,$20,$20,$1f,$1e,$1d,$1c,$1b,$1a,$19 ;00A0
  701.     .byte $18,$17,$17,$16,$15,$14,$13,$12,$11,$10,$0f,$0e,$0d,$0c,$0b,$0a ;00B0
  702.     .byte $09,$08,$07,$06,$05,$04,$03,$02,$01,$00,$ff,$fe,$fd,$fc,$fb,$fa ;00C0
  703.     .byte $f9,$f8,$f7,$f6,$f5,$f4,$f3,$f2,$f1,$f0,$ef,$ee,$ed,$ec,$eb,$ea ;00D0
  704.     .byte $ea,$e9,$e8,$e7,$e6,$e5,$e4,$e3,$e2,$e1,$e0,$e0,$df,$de,$dd,$dc ;00E0
  705.     .byte $db,$db,$da,$d9,$d8,$d7,$d7,$d6,$d5,$d4,$d4,$d3,$d2,$d2,$d1,$d0 ;00F0
  706.     .byte $d0,$cf,$ce,$ce,$cd,$cc,$cc,$cb,$cb,$ca,$ca,$c9,$c9,$c8,$c8,$c7 ;0100
  707.     .byte $c7,$c6,$c6,$c5,$c5,$c5,$c4,$c4,$c4,$c3,$c3,$c3,$c2,$c2,$c2,$c2 ;0110
  708.     .byte $c1,$c1,$c1,$c1,$c1,$c1,$c0,$c0,$c0,$c0,$c0,$c0,$c0,$c0,$c0,$c0 ;0120
  709.     .byte $c0,$c0,$c0,$c0,$c0,$c0,$c1,$c1,$c1,$c1,$c1,$c1,$c2,$c2,$c2,$c2 ;0130
  710.     .byte $c3,$c3,$c3,$c4,$c4,$c4,$c5,$c5,$c5,$c6,$c6,$c7,$c7,$c8,$c8,$c9 ;0140
  711.     .byte $c9,$ca,$ca,$cb,$cb,$cc,$cc,$cd,$ce,$ce,$cf,$cf,$d0,$d1,$d1,$d2 ;0150
  712.     .byte $d3,$d4,$d4,$d5,$d6,$d7,$d7,$d8,$d9,$da,$da,$db,$dc,$dd,$de,$df ;0160
  713.     .byte $df,$e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e8,$e9,$ea,$eb,$ec,$ed ;0170
  714.     .byte $ee,$ef,$f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd ;0180
  715.     .byte $fe,$ff                                                         ;0190
  716.  
  717. .segment "VECTORS"
  718.     .addr _vblank
  719.     .addr _reset  ;program counter initializes here iirc
  720.     .addr _irq
  721.  
  722. .segment "CHARS_A" ;left pattern table
  723.     ;0: amogus
  724.     .byte %00111111
  725.     .byte %00111111
  726.     .byte %11110111
  727.     .byte %11110000
  728.     .byte %11111111
  729.     .byte %11111111
  730.     .byte %00110011
  731.     .byte %00110011 ;
  732.     .byte %00000000
  733.     .byte %00000000
  734.     .byte %00001111
  735.     .byte %00001111
  736.     .byte %00000000
  737.     .byte %00000000
  738.     .byte %00000000
  739.     .byte %00000000 ;
  740.    
  741.     ;1: paddle left
  742.     .byte %01011101
  743.     .byte %00101110
  744.     .byte %01011101
  745.     .byte %00101110
  746.     .byte %01011101
  747.     .byte %00101110
  748.     .byte %01011101
  749.     .byte %00101110 ;
  750.     .byte %00000010
  751.     .byte %00000001
  752.     .byte %00000010
  753.     .byte %00000001
  754.     .byte %00000010
  755.     .byte %00000001
  756.     .byte %00000010
  757.     .byte %00000001 ;
  758.     ;2: paddle right
  759.     .byte %00010111
  760.     .byte %10001011
  761.     .byte %00010111
  762.     .byte %10001011
  763.     .byte %00010111
  764.     .byte %10001011
  765.     .byte %00010111
  766.     .byte %10001011 ;
  767.     .byte %11111111
  768.     .byte %01111111
  769.     .byte %11111111
  770.     .byte %01111111
  771.     .byte %11111111
  772.     .byte %01111111
  773.     .byte %11111111
  774.     .byte %01111111 ;
  775.    
  776.     ;stars (this could just be 1 pattern with palette swaps)
  777.     ;0/3
  778.     .byte %00000000
  779.     .byte %00010000
  780.     .byte %00101000
  781.     .byte %01010100
  782.     .byte %00101000
  783.     .byte %00010000
  784.     .byte %00000000
  785.     .byte %00000000 ;
  786.     .byte %00010000
  787.     .byte %01010100
  788.     .byte %00111000
  789.     .byte %11101110
  790.     .byte %00111000
  791.     .byte %01010100
  792.     .byte %00010000
  793.     .byte %00000000 ;
  794.     ;1/3
  795.     .byte %00010000
  796.     .byte %01000100
  797.     .byte %00010000
  798.     .byte %10101010
  799.     .byte %00010000
  800.     .byte %01000100
  801.     .byte %00010000
  802.     .byte %00000000 ;
  803.     .byte %00010000
  804.     .byte %01010100
  805.     .byte %00101000
  806.     .byte %11010110
  807.     .byte %00101000
  808.     .byte %01010100
  809.     .byte %00010000
  810.     .byte %00000000 ;
  811.     ;2/3
  812.     .byte %00000000
  813.     .byte %00010000
  814.     .byte %00101000
  815.     .byte %01010100
  816.     .byte %00101000
  817.     .byte %00010000
  818.     .byte %00000000
  819.     .byte %00000000 ;
  820.     .byte %00010000
  821.     .byte %01000100
  822.     .byte %00010000
  823.     .byte %10111010
  824.     .byte %00010000
  825.     .byte %01000100
  826.     .byte %00010000
  827.     .byte %00000000 ;
  828.     ;3/3
  829.     .byte %00010000
  830.     .byte %01000100
  831.     .byte %00010000
  832.     .byte %10101010
  833.     .byte %00010000
  834.     .byte %01000100
  835.     .byte %00010000
  836.     .byte %00000000 ;
  837.     .byte %00000000
  838.     .byte %00010000
  839.     .byte %00111000
  840.     .byte %01111100
  841.     .byte %00111000
  842.     .byte %00010000
  843.     .byte %00000000
  844.     .byte %00000000 ;
  845.  
  846. .segment "CHARS_B" ;right pattern table
  847.  
  848.     .byte %10000001
  849.     .byte %00000000
  850.     .byte %00000000
  851.     .byte %00000000
  852.     .byte %00000000
  853.     .byte %00000000
  854.     .byte %00000000
  855.     .byte %10000001 ;
  856.     .byte %10000001
  857.     .byte %00000000
  858.     .byte %00000000
  859.     .byte %00000000
  860.     .byte %00000000
  861.     .byte %00000000
  862.     .byte %00000000
  863.     .byte %10000001 ;
  864.  
  865. .include "text8x8.inc"
  866.  
  867. .segment "DATA"
Add Comment
Please, Sign In to add comment