00 C0 A2 00 20 CF FF C9 0D 9D 02 C1 F0 03 E8 D0 F3 20 D2 FF A5 7A 85 FB A5 7B
85 FC A9 01 85 7A A9 C1 85 7B 20 73 00 20 6B A9 A5 14 85 FD A5 15 85 FE 20 73
00 20 6B A9 A5 FB 85 7A A5 FC 85 7B A5 14 4A 4A 4A AA 20 F0 E9 A5 FD 46 FE 6A
4A 4A A8 A5 14 29 07 AA A9 00 38 6A CA 10 FC 85 FE B1 D1 0A 26 FC 0A 26 FC 0A
26 FC 85 FB A5 D2 29 03 09 D8 85 D2 B1 D1 85 02 A9 02 18 2D 18 D0 0A 0A 65 FC
29 0F 09 D0 85 FC A9 33 85 01 A5 FD 29 07 A8 B1 FB A2 37 86 01 25 FE D0 05 AD
21 D0 85 02 A6 D6 20 F0 E9 A5 02 29 0F AA BC D2 C0 20 BC C0 BC E2 C0 20 B7 C0
BC F2 C0 A9 2C 20 D2 FF 98 0A A9 30 90 02 A9 31 20 D2 FF A9 2E 20 D2 FF 98 29
7F 4C D2 FF 30 B0 35 35 36 33 32 39 36 33 38 33 35 37 34 37 30 B0 32 38 32 37
32 39 33 32 34 33 35 B0 34 37 30 B0 32 38 36 33 36 34 32 30 34 33 35 36 39 37
Esperaba que esto fuera posible en muchos menos bytes, pero desafortunadamente ... bueno, desde que lo terminé, publicando ahora de todos modos. Al menos, el formato restrictivo ayudó con una cosa: algo similar a stdin
(entrada desde un dispositivo actual) solo existe en el C64 en modo de texto, porque el sistema operativo solo admite este modo, por lo que no es necesario considerar otros modos del chip de gráficos .
Nota sobre la salida de los valores de color: el chip gráfico C64 no usa colores RGB, sino que genera directamente una señal de video con colores YUV, con una paleta fija de 16 colores. Utilicé valores redondeados de la conversión de colodore a RGB con la configuración de monitor "predeterminada" aquí.
-20 bytes : mejor rutina de salida, codificando la salida de 3 caracteres por canal de color en un solo byte.
Con respecto al comentario: en teoría es posible usar incluso el modo de caracteres multicolor del VIC con el sistema operativo C64 estándar, pero requiere una fuente personalizada que en realidad sea legible con solo 4 píxeles horizontales de doble ancho. No del todo imposible, pero muy poco probable. Del mismo modo, el modo de color extendido (o el modo de fondo extendido, que es el mismo) podría usarse con el sistema operativo C64, pero requiere reconfigurar el chip de gráficos directamente. Opté por ignorar todas estas posibilidades en el sentido del golf de código aquí: no es el entorno estándar que se encuentra en un Commodore 64 con sistema operativo stock en ejecución. Lo que es posible con el sistema operativo estándar es cambiar entre dos fuentes incorporadas (shift + tecla Commodore), el programa lo explica.
Uso: SYS49152
para comenzar.
Desmontaje comentado :
00 C0 .WORD $C000 ; load address
.C:c000 A2 00 LDX #$00 ; loop index for input
.C:c002 .input:
.C:c002 20 CF FF JSR $FFCF ; character from input device
.C:c005 C9 0D CMP #$0D ; compare with enter
.C:c007 9D 16 C1 STA .buf,X ; store to buffer
.C:c00a F0 03 BEQ .parse ; was enter -> start parsing
.C:c00c E8 INX ; next character
.C:c00d D0 F3 BNE .input ; and repeat input loop
.C:c00f .parse:
.C:c00f 20 D2 FF JSR $FFD2 ; output the enter character
.C:c012 A5 7A LDA $7A ; save pointer of BASIC parser
.C:c014 85 FB STA $FB
.C:c016 A5 7B LDA $7B
.C:c018 85 FC STA $FC
.C:c01a A9 15 LDA #$15 ; set pointer of BASIC parser to
.C:c01c 85 7A STA $7A ; buffer-1
.C:c01e A9 C1 LDA #$C1
.C:c020 85 7B STA $7B
.C:c022 20 73 00 JSR $0073 ; get next character
.C:c025 20 6B A9 JSR $A96B ; BASIC routine to parse number
.C:c028 A5 14 LDA $14 ; lowbyte of parsed number to $fd
.C:c02a 85 FD STA $FD
.C:c02c A5 15 LDA $15 ; highbyte to $fe
.C:c02e 85 FE STA $FE
.C:c030 20 73 00 JSR $0073 ; get next character
.C:c033 20 6B A9 JSR $A96B ; parse as number ...
.C:c036 A5 FB LDA $FB ; restore pointer of BASIC parser
.C:c038 85 7A STA $7A
.C:c03a A5 FC LDA $FC
.C:c03c 85 7B STA $7B
.C:c03e A5 14 LDA $14 ; load y coordinate
.C:c040 4A LSR A ; divide by 8 for character row
.C:c041 4A LSR A
.C:c042 4A LSR A
.C:c043 AA TAX ; -> to X
.C:c044 20 F0 E9 JSR $E9F0 ; set pointer to character row
.C:c047 A5 FD LDA $FD ; divide x coordinate by 8
.C:c049 46 FE LSR $FE
.C:c04b 6A ROR A
.C:c04c 4A LSR A
.C:c04d 4A LSR A
.C:c04e A8 TAY ; -> to Y
.C:c04f A5 14 LDA $14 ; load y coordinate
.C:c051 29 07 AND #$07 ; mask pixel position in character
.C:c053 AA TAX ; -> to X
.C:c054 A9 00 LDA #$00 ; initialize pixel mask to 0
.C:c056 38 SEC ; set carry for bit to shift in
.C:c057 .bitnum:
.C:c057 6A ROR A ; shift bit in mask
.C:c058 CA DEX ; and repeat until
.C:c059 10 FC BPL .bitnum ; in correct position
.C:c05b 85 FE STA $FE ; store pixel mask to $fe
.C:c05d B1 D1 LDA ($D1),Y ; load character code
.C:c05f 0A ASL A ; multiply by 8
.C:c060 26 FC ROL $FC
.C:c062 0A ASL A
.C:c063 26 FC ROL $FC
.C:c065 0A ASL A
.C:c066 26 FC ROL $FC
.C:c068 85 FB STA $FB ; and store to $fb/$fc
.C:c06a A5 D2 LDA $D2 ; move pointer to position in color RAM
.C:c06c 29 03 AND #$03
.C:c06e 09 D8 ORA #$D8
.C:c070 85 D2 STA $D2
.C:c072 B1 D1 LDA ($D1),Y ; load color of character
.C:c074 85 02 STA $02 ; and store to $2
.C:c076 A9 02 LDA #$02 ; check which charset is active
.C:c078 18 CLC
.C:c079 2D 18 D0 AND $D018
.C:c07c 0A ASL A ; and calculate offset
.C:c07d 0A ASL A
.C:c07e 65 FC ADC $FC ; add to (character code * 8)
.C:c080 29 0F AND #$0F
.C:c082 09 D0 ORA #$D0 ; and add offset to character ROM
.C:c084 85 FC STA $FC
.C:c086 A9 33 LDA #$33 ; bank in character ROM
.C:c088 85 01 STA $01
.C:c08a A5 FD LDA $FD ; load y coordinate
.C:c08c 29 07 AND #$07 ; mask pixel-row number
.C:c08e A8 TAY
.C:c08f B1 FB LDA ($FB),Y ; load pixel row from character ROM
.C:c091 A2 37 LDX #$37 ; bank out character ROM
.C:c093 86 01 STX $01
.C:c095 25 FE AND $FE ; apply pixel mask
.C:c097 D0 05 BNE .pixelcol ; not 0 -> pixel is set
.C:c099 AD 21 D0 LDA $D021 ; otherwise load background color
.C:c09c 85 02 STA $02 ; and store to $2
.C:c09e .pixelcol:
.C:c09e A6 D6 LDX $D6 ; restore screen row pointer for
.C:c0a0 20 F0 E9 JSR $E9F0 ; current cursor position
.C:c0a3 A5 02 LDA $02 ; load color
.C:c0a5 29 0F AND #$0F ; mask low nibble (only 16 colors)
.C:c0a7 AA TAX ; -> to X
.C:c0a8 BC D2 C0 LDY .red,X ; load encoded output for red
.C:c0ab 20 BC C0 JSR .out2 ; call output without comma
.C:c0ae BC E2 C0 LDY .green,X ; load encoded output for green
.C:c0b1 20 B7 C0 JSR .out1 ; call output with comma
.C:c0b4 BC F2 C0 LDY .blue,X ; load encoded output for blue
.C:c0b7 .out1:
.C:c0b7 A9 2C LDA #$2C ; load ","
.C:c0b9 20 D2 FF JSR $FFD2 ; and output
.C:c0bc .out2:
.C:c0bc 98 TYA ; encoded output to A
.C:c0bd 0A ASL A ; shift top bit to carry
.C:c0be A9 30 LDA #$30 ; load "0"
.C:c0c0 90 02 BCC .firstdig ; carry clear -> to output
.C:c0c2 A9 31 LDA #$31 ; load "1"
.C:c0c4 .firstdig:
.C:c0c4 20 D2 FF JSR $FFD2 ; and output
.C:c0c7 A9 2E LDA #$2E ; load "."
.C:c0c9 20 D2 FF JSR $FFD2 ; and output
.C:c0cc 98 TYA ; encoded output to A
.C:c0cd 29 7F AND #$7F ; mask out top bit
.C:c0cf 4C D2 FF JMP $FFD2 ; to output and exit
.C:c0d2 .red: ; encoded values for red
.C:c0d2 30 B0 35 35 .BYTE $30,$B0,$35,$35 ; ASCII digit ($30-$39) after
.C:c0d6 36 33 32 39 .BYTE $36,$33,$32,$39 ; decimal point, with bit 7
.C:c0da 36 33 38 33 .BYTE $36,$33,$38,$33 ; indicating 0 or 1 before
.C:c0de 35 37 34 37 .BYTE $35,$37,$34,$37 ; decimal point
.C:c0e2 .green: ; encoded values for green
.C:c0e2 30 B0 32 38 .BYTE $30,$B0,$32,$38 ; ...
.C:c0e6 32 37 32 39 .BYTE $32,$37,$32,$39
.C:c0ea 33 32 34 33 .BYTE $33,$32,$34,$33
.C:c0ee 35 B0 34 37 .BYTE $35,$B0,$34,$37
.C:c0f2 .blue: ; encoded values for blue
.C:c0f2 30 B0 32 38 .BYTE $30,$B0,$32,$38 ; ...
.C:c0f6 36 33 36 34 .BYTE $36,$33,$36,$34
.C:c0fa 32 30 34 33 .BYTE $32,$30,$34,$33
.C:c0fe 35 36 39 37 .BYTE $35,$36,$39,$37
.C:c102 .buf: ; buffer for input ("stdin")
RRR
,GGG
yBBB
ser puntos flotantes entre 0 y 1? Por lo general, son enteros en el rango[0,255]
. Sugeriría permitir ambos.